+0.16 A distributed queue in a single JSON file on object storage (turbopuffer.com S:+0.13 )
169 points by Sirupsen 9 days ago | 55 comments on HN | Mild positive Editorial · v3.7 · 2026-02-26 03:47:48 0
Summary Free Expression & Information Access Acknowledges
This technical blog post demonstrates transparent engineering documentation and public accessibility, with observable positive signals for Article 19 (freedom of information). However, embedded bot detection and tracking infrastructure create privacy concerns under Article 12, and JavaScript-dependent interactive elements generate accessibility barriers affecting Articles 2 and 21. The content is primarily technical rather than human rights-focused, resulting in limited direct engagement with UDHR provisions.
Article Heatmap
Preamble: ND — Preamble Preamble: No Data — Preamble P Article 1: ND — Freedom, Equality, Brotherhood Article 1: No Data — Freedom, Equality, Brotherhood 1 Article 2: ND — Non-Discrimination Article 2: No Data — Non-Discrimination 2 Article 3: ND — Life, Liberty, Security Article 3: No Data — Life, Liberty, Security 3 Article 4: ND — No Slavery Article 4: No Data — No Slavery 4 Article 5: ND — No Torture Article 5: No Data — No Torture 5 Article 6: ND — Legal Personhood Article 6: No Data — Legal Personhood 6 Article 7: ND — Equality Before Law Article 7: No Data — Equality Before Law 7 Article 8: ND — Right to Remedy Article 8: No Data — Right to Remedy 8 Article 9: ND — No Arbitrary Detention Article 9: No Data — No Arbitrary Detention 9 Article 10: ND — Fair Hearing Article 10: No Data — Fair Hearing 10 Article 11: ND — Presumption of Innocence Article 11: No Data — Presumption of Innocence 11 Article 12: ND — Privacy Article 12: No Data — Privacy 12 Article 13: ND — Freedom of Movement Article 13: No Data — Freedom of Movement 13 Article 14: ND — Asylum Article 14: No Data — Asylum 14 Article 15: ND — Nationality Article 15: No Data — Nationality 15 Article 16: ND — Marriage & Family Article 16: No Data — Marriage & Family 16 Article 17: ND — Property Article 17: No Data — Property 17 Article 18: ND — Freedom of Thought Article 18: No Data — Freedom of Thought 18 Article 19: +0.28 — Freedom of Expression 19 Article 20: ND — Assembly & Association Article 20: No Data — Assembly & Association 20 Article 21: ND — Political Participation Article 21: No Data — Political Participation 21 Article 22: ND — Social Security Article 22: No Data — Social Security 22 Article 23: ND — Work & Equal Pay Article 23: No Data — Work & Equal Pay 23 Article 24: ND — Rest & Leisure Article 24: No Data — Rest & Leisure 24 Article 25: ND — Standard of Living Article 25: No Data — Standard of Living 25 Article 26: ND — Education Article 26: No Data — Education 26 Article 27: ND — Cultural Participation Article 27: No Data — Cultural Participation 27 Article 28: ND — Social & International Order Article 28: No Data — Social & International Order 28 Article 29: ND — Duties to Community Article 29: No Data — Duties to Community 29 Article 30: ND — No Destruction of Rights Article 30: No Data — No Destruction of Rights 30
Negative Neutral Positive No Data
Aggregates
Editorial Mean +0.16 Structural Mean +0.13
Weighted Mean +0.28 Unweighted Mean +0.28
Max +0.28 Article 19 Min +0.28 Article 19
Signal 1 No Data 30
Volatility 0.00 (Low)
Negative 0 Channels E: 0.6 S: 0.4
SETL +0.07 Editorial-dominant
FW Ratio 55% 11 facts · 9 inferences
Evidence 9% coverage
1H 3M 27 ND
Theme Radar
Foundation Security Legal Privacy & Movement Personal Expression Economic & Social Cultural Order & Duties Foundation: 0.00 (0 articles) Security: 0.00 (0 articles) Legal: 0.00 (0 articles) Privacy & Movement: 0.00 (0 articles) Personal: 0.00 (0 articles) Expression: 0.28 (1 articles) Economic & Social: 0.00 (0 articles) Cultural: 0.00 (0 articles) Order & Duties: 0.00 (0 articles)
HN Discussion 14 top-level · 13 replies
soletta 2026-02-24 10:42 UTC link
The usual path an engineer takes is to take a complex and slow system and reengineer it into something simple, fast, and wrong. But as far as I can tell from the description in the blog though, it actually works at scale! This feels like a free lunch and I’m wondering what the tradeoff is.
jamescun 2026-02-24 10:48 UTC link
This post touches on a realisation I made a while ago, just how far you can get with the guarantees and trade-offs of object storage.

What actually _needs_ to be in the database? I've never gone as far as building a job queue on top of object storage, but have been involved in building surprisingly consistent and reliable systems with object storage.

dewey 2026-02-24 10:53 UTC link
Depending on who hosts your object storage this seems like it could get much more expensive than using a queue table in your database? But I'm also aware that this is a blog post of an object storage company.
Normal_gaussian 2026-02-24 11:10 UTC link
The original graph appears to simply show the blocking issue of their previous synchronisation mechanism; 10 min to process an item down to 6 min. Any central system would seem to resolve this for them.

In any organisation its good to make choices for simplicity rather than small optimisations - you're optimising maintenance, incident resolution, and development.

Typically I have a small pg server for these things. It'll work out slightly more expensive than this setup for one action, yet it will cope with so much more - extending to all kinds of other queues and config management - with simple management, off the shelf diagnostics etc.

While the object store is neat, there is a confluence of factors which make it great and simple for this workload, that may not extend to others. 200ms latency is a lot for other workloads, 5GB/s doesn't leave a lot of headroom, etc. And I don't want to be asked to diagnose transient issues with this.

So I'm torn. It's simple to deploy and configure from a fresh deployment PoV. Yet it wouldn't be accepted into any deployment I have worked on.

pjc50 2026-02-24 11:17 UTC link
Several things going on here:

- concurrency is very hard

- .. but object storage "solves" most of that for you, handing you a set of semantics which work reliably

- single file throughput sucks hilariously badly

- .. because 1Gb is ridiculously large for an atomic unit

- (this whole thing resembles a project I did a decade ago for transactional consistency on TFAT on Flash, except that somehow managed faster commit times despite running on a 400Mhz MIPS CPU. Edit: maybe I should try to remember how that worked and write it up for HN)

- therefore, all of the actual work is shifted to the broker. The broker is just periodically committing its state in case it crashes

- it's not clear whether the broker ACKs requests before they're in durable storage? Is it possible to lose requests in flight anyway?

- there's a great design for a message queue system between multiple nodes that aims for at least once delivery, and has existed for decades, while maintaining high throughput: SMTP. Actually, there's a whole bunch of message queue systems?

isoprophlex 2026-02-24 11:29 UTC link
Is this reinventing a few redis features with an object storage for persistence?
loevborg 2026-02-24 13:56 UTC link
Love this writeup. There's so much interesting stuff you can build on top of Object Storage + compare-and-swap. You learn a lot about distributed systems this way.

I'd love to see a full sample implementation based on s3 + ecs - just to study how it works.

staticassertion 2026-02-24 14:09 UTC link
Yeah, I mean, I think we're all basically doing this now, right? I wouldn't choose this design, but I think something similar to DeltaLake can be simplified down for tons of use cases. Manifest with CAS + buffered objects to S3, maybe compaction if you intend to do lots of reads. It's not hard to put it together.

You can achieve stupidly fast read/write operations if you do this right with a system that is shocking simple to reason about.

> Step 4: queue.json with an HA brokered group commit > The broker is stateless, so it's easy and inexpensive to move. And if we end up with more than one broker at a time? That's fine: CAS ensures correctness even with two brokers.

TBH this is the part that I think is tricky. Just resolving this in a way that doesn't end up with tons of clients wasting time talking to a broker that buffers their writes, pushes them, then always fails. I solved this at one point with token fencing and then decided it wasn't worth it and I just use a single instance to manage all writes. I'd again point to DeltaLake for the "good" design here, which is to have multiple manifests and only serialize compaction, which also unlocks parallel writers.

The other hard part is data deletion. For the queue it looks deadly simple since it's one file, but if you want to ramp up your scale and get multiple writers or manage indexes (also in S3) then deletion becomes something you have to slip into compaction. Again, I had it at one point and backed it out because it was painful.

But I have 40k writes per second working just fine for my setup, so I'm not worrying. I'd suggest others basically punt as hard as possible on this. If you need more writes, start up a separate index with its own partition for its own separate set of data, or do naive sharding.

motoboi 2026-02-24 14:20 UTC link
By typography alone I can now turbopuffer is written in zig.
salil999 2026-02-24 14:40 UTC link
Reminds me of WarpStream: https://www.warpstream.com

Similar idea but you have the power of S3 scale (if you really need it). For context, I do not work at WS. My company switched to it recently and we've seen great improvements over traditional Kafka.

talentedtumor 2026-02-24 16:16 UTC link
Does this suffer from ABA problem, or does object storage solve that for you by e.g. refusing to accept writes where content has changed between the read and write?
up2isomorphism 2026-02-24 16:49 UTC link
The windows has passed already for this kind of opportunities since there are dozen of people all doing the same thing. Also abusing object storage is not very fun.
hinkley 2026-02-24 19:57 UTC link
For performance reasons we needed a set of assets on all copies of a service. We were using consul for the task management, which is effectively a tree of data that’s tantamount to a json file (in fact we usually pull trees of data as a json file).

Among other problems I knew the next thing we were going to have to do was autoscaling and the system we had for call and response was a mess from that respect. Unanswered questions were: How do you know when all agents have succeeded, how do you avoid overwriting your peers’ data, and what do you do with agents that existed yesterday and don’t today?

I ended up rewriting all of the state management data so that each field had one writer and one or more readers. It also allowed me to move the last live service call for another service and decommission it. Instead of having a admin service you just called one of the peers at random and elected it leader for the duration of that operation. I also arranged the data so the leader could watch the parent key for the roll call and avoid needing to poll.

Each time a task was created the leader would do a service discovery call to get a headcount and then wait for everyone to set a suggests or failure state. Some of these state transitions were idempotent, so if you reissued a task you didn’t need to delete the old results. Everyone who already completed it would noop, and the ones that failed or the new servers that joined the cluster would finish up. If there was a delete operation later then the data would be purged from the data set and the agents, a subsequent call would be considered new.

Long story short, your CS program should have distributed computing classes because this shit is hard to work out from first principles when you don’t know what the principles even are.

ozgrakkurt 2026-02-25 08:41 UTC link
This is really cool but feels like an attack on the pride of software development at the same time.

Just slap some garbage on it and it is better

jrjeksjd8d 2026-02-24 10:48 UTC link
It seems like this is an approach that trades off scale and performance for operational simplicity. They say they only have 1GB of records and they can use a single committer to handle all requests. Failover happens by missing a compare-and-set so there's probably a second of latency to become leader?

This is not to say it's a bad system, but it's very precisely tailored for their needs. If you look at the original Kafka implementation, for instance, it was also very simple and targeted. As you bolt on more use cases and features you lose the simplicity to try and become all things to all people.

formerly_proven 2026-02-24 10:50 UTC link
Write amplification >9000 mostly
dewey 2026-02-24 11:35 UTC link
Assuming you already using object storage in your project, but don't use Redis yet it wouldn't be re-inventing but just avoiding an extra dependency that would only be used by a single feature.
Sirupsen 2026-02-24 12:20 UTC link
(cofounder of tpuf here)

We don't have a relational database, otherwise that would work great for a queue! You can imagine us continuing to iterate here to Step 5, Step 6, ... Step N over time. The tradeoff of each step is complexity, and complexity has to be deserved. This is working exceptionally well currently.

candiddevmike 2026-02-24 12:44 UTC link
AFAIK you can kinda "seek" reads in S3 using a range header, WCGW? =D
jitl 2026-02-24 13:48 UTC link
> The broker runs a single group commit loop on behalf of all clients, so no one contends for the object. Critically, it doesn't acknowledge a write until the group commit has landed in object storage. No client moves on until its data is durably committed.
jitl 2026-02-24 13:51 UTC link
it’s got some more 9s of durability compared to redis (redis did not invent “queue”)
zbentley 2026-02-24 15:06 UTC link
> I solved this at one point with token fencing

Could you expand on that? Even if it wasn't the approach you stuck with, I'm curious.

thomas_fa 2026-02-24 15:10 UTC link
A lot of good insights here. I am also wandering if they can just simply put different jobs (unclaimed, in-progress, deleted/done) into different directory/prefix, and rely on atomic object rename primitive [1][2][3] to solve the problem more gracefully (group commit can still be used if needed).

[1] https://docs.cloud.google.com/storage/docs/samples/storage-m... [2] https://docs.aws.amazon.com/AmazonS3/latest/API/API_RenameOb... [3] https://fractalbits.com/blog/why-we-built-another-object-sto...

soletta 2026-02-24 15:15 UTC link
It is by the juice of Zig that binaries acquire speed, the allocators acquire ownership, the ownership becomes a warning. It is by typography alone I can now turbopuffer is written in zig.
allknowingfrog 2026-02-24 17:07 UTC link
This is news to me. What motivates you to reach for an S3-backed queue versus SQS?
staticassertion 2026-02-24 18:23 UTC link
> refusing to accept writes where content has changed between the read and write?

Right. You can issue a write that will only be accepted if a condition is matched, like the etag of the object matching your expectation. If it doesn't match, your object was invalidated.

tomnicholas1 2026-02-24 19:10 UTC link
What you describe is very similar to how Icechunk[1] works. It works beautifully for transactional writes to "repos" containing PBs of scientific array data in object storage.

[1]: https://icechunk.io/en/latest/

Editorial Channel
What the content says
+0.16
Article 19 Freedom of Expression
High Advocacy Framing
Editorial
+0.16
SETL
+0.07

Blog post demonstrates transparent technical communication and educational intent. Content explains distributed systems design principles clearly and openly, promoting informed understanding of engineering concepts.

ND
Preamble Preamble

Content does not directly address human dignity, equal rights, or the foundational principles of the UDHR.

ND
Article 1 Freedom, Equality, Brotherhood

Blog post contains no reference to equality, freedom, or inherent dignity.

ND
Article 2 Non-Discrimination
Medium

No editorial content directly addressing discrimination.

ND
Article 3 Life, Liberty, Security

No content addressing right to life, liberty, or personal security.

ND
Article 4 No Slavery

No reference to slavery or servitude.

ND
Article 5 No Torture

No discussion of torture or cruel treatment.

ND
Article 6 Legal Personhood

Content does not address right to recognition as a person.

ND
Article 7 Equality Before Law

No reference to equality before the law.

ND
Article 8 Right to Remedy

No discussion of legal remedies or judicial recourse.

ND
Article 9 No Arbitrary Detention

No reference to arbitrary arrest or detention.

ND
Article 10 Fair Hearing

No discussion of fair trial or due process.

ND
Article 11 Presumption of Innocence

No reference to criminal law or presumption of innocence.

ND
Article 12 Privacy
Medium Practice

No editorial content directly addressing privacy.

ND
Article 13 Freedom of Movement

No discussion of freedom of movement.

ND
Article 14 Asylum

No reference to asylum or refuge.

ND
Article 15 Nationality

No discussion of nationality or citizenship.

ND
Article 16 Marriage & Family

No discussion of family, marriage, or property rights.

ND
Article 17 Property

No reference to property rights or confiscation.

ND
Article 18 Freedom of Thought

No discussion of freedom of thought, conscience, or religion.

ND
Article 20 Assembly & Association

No discussion of freedom of assembly or association.

ND
Article 21 Political Participation
Medium

No content addressing participation in government or public affairs.

ND
Article 22 Social Security

No discussion of economic, social, or cultural rights.

ND
Article 23 Work & Equal Pay

No content addressing labor rights or working conditions.

ND
Article 24 Rest & Leisure

No discussion of rest, leisure, or reasonable working hours.

ND
Article 25 Standard of Living

No reference to food, clothing, housing, or social security.

ND
Article 26 Education

No discussion of education or educational rights.

ND
Article 27 Cultural Participation

No reference to participation in cultural life or intellectual property.

ND
Article 28 Social & International Order

No discussion of social and international order.

ND
Article 29 Duties to Community

No reference to community responsibilities or limitations on rights.

ND
Article 30 No Destruction of Rights

No content addressing prevention of UDHR rights destruction.

Structural Channel
What the site does
+0.13
Article 19 Freedom of Expression
High Advocacy Framing
Structural
+0.13
Context Modifier
+0.13
SETL
+0.07

Content is publicly accessible without paywall or registration requirement (access_model +0.05). Editorial code practices demonstrate transparent engineering documentation (+0.08). Together these signal commitment to free expression of technical ideas.

ND
Preamble Preamble

No structural signals related to fundamental human rights affirmation.

ND
Article 1 Freedom, Equality, Brotherhood

No evidence of differential access or exclusionary structures observable.

ND
Article 2 Non-Discrimination
Medium

Accessibility barriers (JavaScript-dependent charts, obfuscated code) may impede access for users with disabilities.

ND
Article 3 Life, Liberty, Security

No observable structural threats to individual security.

ND
Article 4 No Slavery

No observable practices related to forced labor or servitude.

ND
Article 5 No Torture

No structural implications for torture or degradation.

ND
Article 6 Legal Personhood

No observable structural barriers to legal personhood.

ND
Article 7 Equality Before Law

No observable unequal legal treatment.

ND
Article 8 Right to Remedy

Not applicable to technical blog content.

ND
Article 9 No Arbitrary Detention

No observable implications for arrest or detention.

ND
Article 10 Fair Hearing

Not applicable to technical documentation.

ND
Article 11 Presumption of Innocence

Not applicable.

ND
Article 12 Privacy
Medium Practice

Embedded bot detection (KPSDK) and challenge mechanisms indicate tracking/surveillance infrastructure that may compromise privacy boundaries.

ND
Article 13 Freedom of Movement

No observable structural implications.

ND
Article 14 Asylum

Not applicable.

ND
Article 15 Nationality

Not applicable.

ND
Article 16 Marriage & Family

Not applicable.

ND
Article 17 Property

Not applicable.

ND
Article 18 Freedom of Thought

Not applicable.

ND
Article 20 Assembly & Association

No observable structural implications.

ND
Article 21 Political Participation
Medium

Accessibility barriers may impede participation for users with disabilities; JavaScript-dependent interactive elements create structural impediments.

ND
Article 22 Social Security

Not applicable.

ND
Article 23 Work & Equal Pay

Not applicable to blog content.

ND
Article 24 Rest & Leisure

Not applicable.

ND
Article 25 Standard of Living

Not applicable.

ND
Article 26 Education

While the blog provides educational content, this is not specifically focused on education rights.

ND
Article 27 Cultural Participation

Not applicable.

ND
Article 28 Social & International Order

Not applicable.

ND
Article 29 Duties to Community

Not applicable.

ND
Article 30 No Destruction of Rights

Not applicable.

Supplementary Signals
How this content communicates, beyond directional lean. Learn more
Epistemic Quality
How well-sourced and evidence-based is this content?
0.75 low claims
Sources
0.8
Evidence
0.8
Uncertainty
0.7
Purpose
0.8
Propaganda Flags
No manipulative rhetoric detected
0 techniques detected
Emotional Tone
Emotional character: positive/negative, intensity, authority
measured
Valence
+0.3
Arousal
0.4
Dominance
0.5
Transparency
Does the content identify its author and disclose interests?
0.50
✓ Author
More signals: context, framing & audience
Solution Orientation
Does this content offer solutions or only describe problems?
0.67 solution oriented
Reader Agency
0.7
Stakeholder Voice
Whose perspectives are represented in this content?
0.35 2 perspectives
Speaks: corporationindividuals
About: workersinstitution
Temporal Framing
Is this content looking backward, at the present, or forward?
present short term
Geographic Scope
What geographic area does this content cover?
global
Complexity
How accessible is this content to a general audience?
technical high jargon domain specific
Longitudinal · 5 evals
+1 0 −1 HN
Audit Trail 25 entries
2026-02-28 14:35 eval_success Lite evaluated: Neutral (0.00) - -
2026-02-28 14:35 eval Evaluated by llama-3.3-70b-wai: 0.00 (Neutral)
reasoning
Technical blog post
2026-02-26 23:08 eval_success Light evaluated: Neutral (0.00) - -
2026-02-26 23:08 eval Evaluated by llama-4-scout-wai: 0.00 (Neutral)
2026-02-26 20:16 dlq Dead-lettered after 1 attempts: A distributed queue in a single JSON file on object storage - -
2026-02-26 20:14 rate_limit OpenRouter rate limited (429) model=llama-3.3-70b - -
2026-02-26 20:13 rate_limit OpenRouter rate limited (429) model=llama-3.3-70b - -
2026-02-26 20:12 rate_limit OpenRouter rate limited (429) model=llama-3.3-70b - -
2026-02-26 17:36 dlq Dead-lettered after 1 attempts: A distributed queue in a single JSON file on object storage - -
2026-02-26 17:35 rate_limit OpenRouter rate limited (429) model=llama-3.3-70b - -
2026-02-26 17:34 rate_limit OpenRouter rate limited (429) model=llama-3.3-70b - -
2026-02-26 17:32 rate_limit OpenRouter rate limited (429) model=llama-3.3-70b - -
2026-02-26 09:09 dlq Dead-lettered after 1 attempts: A distributed queue in a single JSON file on object storage - -
2026-02-26 09:09 dlq Dead-lettered after 1 attempts: A distributed queue in a single JSON file on object storage - -
2026-02-26 09:07 rate_limit OpenRouter rate limited (429) model=mistral-small-3.1 - -
2026-02-26 09:07 rate_limit OpenRouter rate limited (429) model=hermes-3-405b - -
2026-02-26 09:06 rate_limit OpenRouter rate limited (429) model=mistral-small-3.1 - -
2026-02-26 09:06 rate_limit OpenRouter rate limited (429) model=hermes-3-405b - -
2026-02-26 09:05 rate_limit OpenRouter rate limited (429) model=hermes-3-405b - -
2026-02-26 09:05 rate_limit OpenRouter rate limited (429) model=mistral-small-3.1 - -
2026-02-26 09:04 dlq Dead-lettered after 1 attempts: A distributed queue in a single JSON file on object storage - -
2026-02-26 09:02 rate_limit OpenRouter rate limited (429) model=qwen3-next-80b - -
2026-02-26 03:47 eval Evaluated by claude-haiku-4-5-20251001: -0.01 (Neutral) 12,828 tokens -0.01
2026-02-26 02:59 eval Evaluated by claude-haiku-4-5-20251001: -0.00 (Neutral) 12,901 tokens -0.09
2026-02-26 00:57 eval Evaluated by claude-haiku-4-5-20251001: +0.08 (Neutral) 13,175 tokens