Back to blog
6 min read

NetQuack 4000x Faster

We rewrote the NetQuack DuckDB extension from scratch, replacing regex parsing and database queries with character-by-character parsing and perfect hash lookups. The result? Up to 4000x performance improvements—turning 37-second URL extractions into 0.012-second operations.

Listen to this article (Gen-AI)0:00
0:00
Share onX

When we started using DuckDB more heavily at Altertable, we quickly discovered the NetQuack (community-maintained) extension for URL parsing. While functional, its performance was... disappointing. Extracting domains from URLs was taking 37 seconds for 30,000 URLs. For a database that prides itself on analytical performance, this felt wrong.

After digging into the code, the culprits were obvious: heavy reliance on

Loading code...
for parsing and database queries to validate TLDs against the Public Suffix List. Inspired by how ClickHouse handles URL parsing, we rewrote the entire extension. The results? Up to 4000x performance improvements across all functions.

What Was Wrong

The original NetQuack implementation had two major performance killers. First, every URL component extraction used

Loading code...
:

Loading code...

Second, TLD extraction required querying a database table populated from the Mozilla Public Suffix List:

Loading code...

This meant every domain extraction triggered multiple database queries. For analytical workloads processing thousands of URLs, this was a disaster.

The ClickHouse-Inspired Solution

We completely rewrote the extension using character-by-character parsing instead of regex:

Loading code...

This approach uses

Loading code...
for zero-copy operations, processes one character at a time with simple switch statements, and avoids regex compilation overhead entirely.

Then, the bigger win was eliminating database dependencies. We use

Loading code...
to generate a perfect hash function from Mozilla's Public Suffix List:

Loading code...

This creates a collision-free hash function compiled directly into the extension binary. Now TLD lookups are O(1) memory operations instead of database queries:

The perfect hash table adds only ~500KB to the binary size but eliminates runtime PSL downloads, database table storage, query execution overhead, and memory allocations for temporary strings.

Loading code...

The Results

We benchmarked both versions against 30,000 URLs. The improvements were staggering:

FunctionBeforeAfterImprovement
Loading code...
0.069s0.010s6.9x faster
Loading code...
0.086s0.008s10.7x faster
Loading code...
0.533s0.009s59.2x faster
Loading code...
0.127s0.008s15.8x faster
Loading code...
0.202s0.004s50.5x faster
Loading code...
37.503s0.012s3125.2x faster
Loading code...
35.831s0.010s3583.1x faster
Loading code...
36.003s0.009s4000.3x faster
Loading code...
0.329s0.007s47.0x faster

The TLD-dependent functions saw the most dramatic improvements because they eliminated both regex parsing AND database queries. The architecture change was fundamental:

  • Before:
    Loading code...
  • After:
    Loading code...

The old implementation had O(n) regex compilation per URL plus O(log n) database queries with disk I/O. The new implementation has O(n) single-pass character scanning with O(1) perfect hash lookups in memory.

And despite the complete rewrite, all existing tests pass and edge cases are handled correctly.

Key Takeaways

Profile before optimizing. The 37-second domain extraction time immediately pointed to the real bottlenecks. Always measure first.

Eliminate I/O in hot paths. Database queries in URL parsing functions were the primary performance killer. Moving to compile-time data structures eliminated this entirely.

Character parsing beats regex for simple patterns. For structured data like URLs, character-by-character parsing is often faster and more predictable than regex.

Perfect hashing works great for static data. When you have a known, static dataset (like TLDs), perfect hash functions provide optimal lookup performance.

Zero-copy string operations matter. Using

Loading code...
eliminated unnecessary string copying, especially important for analytical workloads.

Try It Yourself

The optimized NetQuack extension is currently under review in Pull Request #13. While we wait for the maintainer to review and hopefully merge these changes, you can:

  1. Test the optimized version by building from our branch:

    Loading code...
  2. Run the benchmarks yourself to see the performance improvements:

    Loading code...
  3. Check out the source code on GitHub to see the detailed implementation.


This optimization journey reminded us why performance matters in analytical databases. When you're processing millions of URLs, the difference between 37 seconds and 0.012 seconds isn't just a nice-to-have—it's the difference between interactive analysis and waiting for coffee to brew.

Sometimes the best optimization is throwing out the old approach entirely and starting fresh with the right architectural principles. In this case, ClickHouse showed us the way.

Share onX
Sylvain Utard, Co-Founder & CEO at Altertable

Sylvain Utard

Co-Founder & CEO

Seasoned leader in B2B SaaS and B2C. Scaled 100+ teams at Algolia (1st hire) & Sorare. Passionate about data, performance and productivity.

We're hiring! Join our team.View All Jobs
Altertable Logo Shard
About Altertable
We're building a unified, AI-driven data platform that puts data to work for people.
Craft with Purpose
Focus with Ownership
Operate with Transparency
Grow with Others