Build1 distinct publisher3 min readUpdated
A team dropped GoAccess because its panels never cross, then spent the engineering effort where it actually lands: keeping ingestion at 44.5 MB regardless of file size.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
A team building crawler reporting on Laravel 13, Horizon and PostgreSQL 18 threw out GoAccess and wrote thirteen log parsers instead, because the question they sell answers to is which crawler fetched which URL, on which day, and with what status code [31][1][7]. That is not a bigger version of "how many hits yesterday" [1]; it is a different shape of answer, and the shape is what forces the build. The reason is worth reading slowly, because everything downstream follows from it. GoAccess emits a report.json of panels: top URLs, top user agents, status code distribution, hits per day, each one already aggregated and none of them crossed with any other [3]. So it will tell you that Googlebot fetched 40,000 pages, and separately that 3,000 requests returned 404, and it cannot tell you whether Googlebot got any of those 404s [4]. The author's line is the cleanest statement of the trade I have seen: "An aggregate you cannot cross is not data. It is a picture of data." [5] The requirement was a cube of date, hour, bot, URL and status code with hit counts and bytes, and once aggregation has to happen on your axes, no report-producing tool helps [6][2]. Owning the parser means owning thirteen input formats [7]. Seven are variations on the common log format and share one engine, GoAccess-style format strings compiled to a regex once and applied per line [8], which leaves six needing dedicated parsers [1]: Cloudflare JSON, Caddy JSON, Google Cloud Storage CSV, and a W3C parser that has to be stateful because IIS declares its columns in a #Fields: header partway through the file [13]. That same W3C parser handles CloudFront, whose lines are URL encoded and whose spaces arrive as plus signs [14]. Two details show where the real cost sits: %^ means "skip this field", which is how a 17-column S3 line fits in one format string [9][10], and %z is their own extension, capturing the UTC offset so timestamps normalise at parse time rather than query time [11]. Get that wrong and a daily report has 25 hours in it twice a year [12]. The benchmark, run 19 August 2026 through the real three stages of parse, classify agent, normalise URL, used a synthetic corpus deliberately hostile to memoization: 5,000 distinct paths and 240 distinct agent strings [15][16], about 1.2 million path-agent combinations [2]. The author declines to lead with throughput [32] and flags that real production logs ran nearer 52,000 lines per second because real agent strings are longer and messier [17], and that synthetic corpora flatter any parser [18]. The load-bearing number is that peak memory was 44.5 MB in that run and 44.5 MB in a previous run with a fraction of the cardinality, because nothing accumulates [19]. A 2 GB file costs the same 44.5 MB as an 86 MB one, roughly 24 times the input for identical memory [20][3], which makes the job's memory limit a constant rather than a function of what a customer uploads [21]. The write side is built for the same property. The aggregate table's unique key is the cube itself [22]; bot_token defaults to an empty string and is never null, because a null inside a unique key stops the index deduplicating [23][24]. PostgreSQL has NULLS NOT DISTINCT, SQLite, which their tests run on, does not, so the sentinel is the portable answer and every column in a uniqueness key is NOT NULL [25][26]. The upsert adds rather than replaces, which is what makes the pipeline restartable: a flush that wrote half a buffer whose keys reappear later is still correct, and two servers' logs covering the same hour merge [28][29][30]. Watch two things. The gap between synthetic and production throughput is the honest measure of the agent classifier, not the parser [17][18].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
The benchmark was run on 19 August 2026 on the author's machine, running the real three stages: parse the line, classify the user agent, normalize the URL.
The benchmark corpus is synthetic but deliberately hostile to memoization, with 5,000 distinct paths and 240 distinct agent strings.
The write is an additive upsert: on conflict on the six cube columns, hit_count and bytes_transferred are incremented by the excluded values rather than replaced.
Adding rather than replacing makes the pipeline restartable: a flush that wrote half a buffer whose keys reappear in a later flush is still correct.
Two log files from two servers covering the same hour merge under the additive upsert.
The product needs to answer which crawler fetched which URL, on which day, and what status code it got: the cross product, not 'how many hits yesterday'.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Detailed first-party account, no external verification
The source supplies unusually concrete artifacts for a build log — parser format strings, the migration's six-column unique index, the additive-upsert SQL, named format families, and a dated measurement — and volunteers caveats about synthetic corpora and slower real-log throughput. But every claim comes from one publisher and one author, there is no repository, harness or raw benchmark output, and the supplied body is truncated before the encoding-incident resolution, so nothing is independently checkable.
One team's own production pipeline
Adoption evidence is limited to the authoring team: a production deployment on Laravel 13, Horizon and PostgreSQL 18 handling real customer log uploads, plus one self-run benchmark. There is no third-party use, no released library or repository, no download or customer counts, and no other publisher observing the technique in the wild.
Slightly understated relative to what is shown
The framing runs against hype: the author explicitly demotes throughput in favour of flat memory, labels the corpus synthetic, discloses a slower real-world rate, and describes a production incident caused by their own design. The claims stay within what the shown code and measurements support, and the transferable schema reasoning is arguably underplayed relative to the benchmark discussion, so the gap sits marginally negative rather than at zero.
First-party post about the author's own commercial product
The author is describing infrastructure behind their own customer-facing crawler-analytics product on a self-publishing developer platform, which creates a competence-marketing incentive and a motive to frame the rejected alternative unfavourably. Mitigating factors are visible: GoAccess is called 'an excellent tool', no pricing, funding or product pitch appears in the supplied body, and the negative disclosures (slower real logs, production incident) work against pure promotion.
Internally coherent but single-sourced
Confidence is capped by structure, not by contradiction: one publisher, one author, no corroboration, and a truncated body. Within those limits the account is internally consistent, code-backed, dated, and self-caveated, so the design claims can be relied on as an accurate description of one team's system while the performance figures should be treated as unaudited.
build
Four REST calls became one query: the sidecar pattern, minus the marketing1 distinct publisher
security
CDN Tsunami: the protocol translation you pay for is the amplifier1 distinct publisher
build
The streaming edit is a software layer: proxies, stubs and an ffmpeg hook on storage you own1 distinct publisher
build
Laravel's session cookie is why your HTML never gets cached at the edge1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 20, 2026