S4E394 — A Modern Web App in C

October 13, 2026 · 13 min

Show notes

A “modern” web app in C turns into a knife fight over one statically linked binary, SQLite’s single-writer rules, and whether brutal simplicity is discipline or just beautifully documented risk.

Sources

Read the transcript

Transcript

GARY: —so CGI is either payment processing or horse medicine.

MAEVE: Neither. You opened the wrong century.

GARY: Fine. I’m Gary. I entered through a legacy interface.

MAEVE: Maeve. I price the interface.

OBI: Obi. I eventually have to operate it.

GRUNER: Gruner. I study why you deserve outages.

GARY: “A Modern Web App in C.” Corey Prophitt shipped marketyour.games commercially.

MAEVE: Accounts, search, folders. A functioning acquisition target.

OBI: Stripe payments. Postmark email. Progressive enhancement.

GRUNER: No required JavaScript. Primitive tribe shows restraint.

GARY: The stack is OpenBSD, C, httpd, CGI, SQLite.

MAEVE: One statically linked binary, plus a SQLite file.

GARY: Vertical integration.

MAEVE: You learned my phrase and injured it.

OBI: Three additional libraries. Embedded assets. No separate database server.

GARY: Deployment means replacing one file. New requests get the new binary.

GRUNER: Serverless without landlord.

GARY: Exactly. It’s visionary architecture from 1994.

OBI: Say how each request is served.

GARY: The web server invokes the program.

OBI: Say the expensive noun.

GARY: It starts a fresh process per request.

MAEVE: Every customer receives a bespoke company.

GARY: Then the company dies cleanly. No lingering state.

OBI: The state is in SQLite, Gary.

GARY: Yes, but emotionally, very clean.

GRUNER: Who owns only write lock?

GARY: We haven’t reached the database argument.

GRUNER: Database has reached us.

OBI: The article also uses pledge, unveil, and httpd’s chroot.

MAEVE: So one binary owns product, frontend, and business logic.

GARY: One binary. You can understand the whole thing.

OBI: Or misunderstand it without distributed assistance.

GARY: That is still fewer meetings.

MAEVE: I can fund one binary. It cannot form a coalition.

GRUNER: Single writer.

GARY: That sounds disciplined.

OBI: It sounds like your preferred board structure.

GARY: A decisive architecture is not automatically fascist.

MAEVE: Correct. Sometimes it merely has Stripe.

GRUNER: Modern means old system owns payment credentials.

MAEVE: Fmo91: “It’s not very clear to me why the author has chosen C.”

GARY: Because choosing C is an achievement before compilation.

GRUNER: In C, even mistake is artisanal.

OBI: The application needs HTTP, SQLite, and careful input handling.

MAEVE: Gary heard “careful” and discovered product-market fit.

GARY: Layer8, quoting the first clause: “The underlying libraries you use tend to be in C anyway.”

GRUNER: Drink river closer to pollution.

GARY: Native interfaces. No extra runtime. Fewer moving parts.

MAEVE: And fewer witnesses when the fucking pointer escapes.

GARY: Kanbankaren: “For any greenfield project, pick up C++ in lieu of C if you want a C language.”

OBI: That buys stronger types, namespaces, references, and several new religions.

GARY: The author says, “It’s too easy to keep reaching into C++ for ‘just one more thing.’”

GRUNER: C++ is minibar. Everything costs later.

GARY: Exactly. C has a hard upper feature bound.

OBI: It has fewer language features, not fewer ways to corrupt memory.

GARY: But the danger is bounded. You know which knives exist.

OBI: Your argument is that an unlocked drawer has excellent inventory.

GARY: No, my argument is constraints prevent architectural sprawl—

OBI: They prevent guardrails.

GARY: Guardrails create false confidence. C gives honest consequences.

OBI: Your bullshit now has deterministic allocation.

GARY: If I exceed a fixed buffer, I immediately learn the limit.

OBI: Your users learn it first, through malformed input.

GARY: Then validation becomes part of the product.

OBI: You have renamed framework responsibilities “customer research.”

GARY: I’m saying a small language keeps ambition physically accountable.

OBI: You want compiler-enforced founder discipline from a compiler permitting undefined behavior.

GARY: Undefined does not mean infinite. It means locally surprising.

OBI: Locally surprising is how a process describes dying.

GARY: Still cleaner than importing six hundred packages to render a button.

GRUNER: Blyat. Gary has become native dependency.

GARY: Kevin_Flynn: “I can never figure out why everything isn’t in C. :|”

MAEVE: There. Gary has achieved comment compatibility.

OBI: Ricardobeat replies: “Is it because you segfault before reaching the answer?”

MAEVE: Panzerschrek: “Does SQLite allow simultaneous write access from multiple processes?”

GARY: Absolutely. Simultaneous access, sequential permission. Like democracy with appointments.

OBI: The author answers: “SQLite can handle multiple concurrent requests if it’s set to WAL mode.”

GRUNER: Humans discover queue. Rename innovation.

OBI: “Reading is all non-blocking/concurrent but writing is still synchronous.”

GARY: Many readers, one adult holding the pen.

MAEVE: Your preferred board structure has reached the database.

OBI: The author adds: “You should also set the ‘busy timeout’ or else your blocked writes will timeout immediately.”

GARY: Good. The database teaches patience through consequences.

GRUNER: Chyort. Database is stricter parent.

GARY: Serialized writes are orderly governance. Nobody wants concurrent legislation.

OBI: WAL lets readers continue while one writer holds the lock.

GARY: Exactly. The public remains informed during executive action.

OBI: Other writers wait. The busy timeout decides how long.

GARY: Which is healthier than letting every fucking request seize power.

OBI: Your database policy is now emergency rule with a millisecond constitution.

GARY: But EGreg says, “Forking a new process can take around 8ms.”

OBI: EGreg says it can. This product did not benchmark it.

GARY: Eight milliseconds is still remarkably cheap for total institutional renewal.

OBI: You are pricing process creation without startup work, request load, or traffic.

GARY: Those are implementation details, and the implementation is deliberately comprehensible—

OBI: Your bullshit has a timeout.

GARY: No, it has a bounded waiting policy. That is responsible capacity planning.

GARY: —ponsible because blocked writers know precisely when they fail.

OBI: They know when SQLite returns busy.

GARY: Failure with a documented return code is governance.

OBI: It is an error path you must handle correctly.

GARY: Which I would, after reproducing it locally.

OBI: With whose concurrent payment request?

GARY: Mine. Repeatedly. Under controlled conditions.

OBI: Td521534f12 supplies the parent context: multiple connections may write, but they take turns.

OBI: “There can only be a single writer at a time to an SQLite database.”

GARY: A single writer preserves coherence.

OBI: Gary, you are that single writer: readers proceed while your bullshit blocks every write.

GRUNER: UltraSane: “Connecting any C code to the internet is a terrible idea.”

GARY: The internet is where C already keeps its knives.

MAEVE: A mature market in uninsurable cutlery.

OBI: Pledge, unveil, chroot, validation. Those precautions are the argument.

GARY: So internet C is acceptable when properly supervised.

OBI: Gary, your dependency-counting dickhead arithmetic is not supervision.

GARY: I supervise by reducing the number of suspects.

OBI: Memory corruption requires one suspect.

GRUNER: Assimpleaspossi replies: “Your server, operating system and database might all be written in C right now.”

GARY: Exactly. The poison has excellent distribution.

MAEVE: Infrastructure enjoys incumbent immunity.

OBI: Widely deployed C proves ubiquity. It does not prove safety.

GARY: But competent hands, narrow scope, hard sandbox—

OBI: And relentless testing.

GARY: Yes. The traditional four-factor authentication.

GRUNER: Nostrademons: “Why C instead of Rust if you’re using AI anyway?”

MAEVE: Rust offers memory safety with a larger merchant fleet.

GARY: Cargo is literally named after supply-chain exposure.

MAEVE: This is the Hanseatic League of software.

OBI: Crates do not arrive by Baltic cog.

MAEVE: No. They arrive through trusted ports with unsigned manifests.

GRUNER: Field note: venture woman discovers fucking guild.

MAEVE: The guild lowers transaction costs through collective dependency enforcement.

OBI: It also expands the number of maintainers you must trust.

MAEVE: Precisely. Lübeck was the package index.

GARY: Was Hamburg a lockfile?

MAEVE: Hamburg was reproducible shipping.

GRUNER: Gary is control group for poisoned cargo.

GRUNER: Joshheitzman: “The memory safety Rust offers isn’t worth the supply chain risks.”

OBI: That is the tradeoff claim. It is not a security verdict.

GARY: Small dependency graph, smaller betrayal radius.

OBI: Zanecodes answers: “You can vendor dependencies in Rust just as easily as you can in C.”

MAEVE: A private warehouse. Still Hanseatic.

GRUNER: Ygg2: “C (and C++) has a supply chain. It’s called unpaid Linux maintainers.”

GARY: So the warehouse runs on invisible civic labor.

OBI: As does your entire minimalist republic.

MAEVE: How many foreign merchants does this application admit?

OBI: Three additional libraries.

MAEVE: He shipped. That matters.

GRUNER: Three libraries: libcurl, libsodium, libcjson. Blyat.

OBI: The article says he built cookie parsing, query handling, form validation, and escaping.

GARY: Good. Those are small, dignified utilities.

MAEVE: Four framework departments hidden inside one header.

GRUNER: One binary contains many tiny landlords.

OBI: The author rolled cgi.h himself.

GARY: Which keeps responsibility legible.

OBI: He also says, “I’m not convinced that was the right solution.”

GARY: Healthy uncertainty is part of responsible ownership—

OBI: Your bullshit has cookies.

GARY: Every architecture has cookies. His are simply handmade and potentially consequential.

MAEVE: Artisanal liability. Strong fucking margins.

GRUNER: Complexity did not leave. Changed mailing address.

OBI: Pledge, unveil, and chroot narrow damage. They do not parse input.

GARY: But he knows where every dangerous function lives.

OBI: Yes. Beside all the customer data.

GARY: That is unusually comprehensible danger.

MAEVE: And unusually concentrated diligence.

GRUNER: Author owns simplicity. Simplicity owns author.

GARY: Afavour: “A shame to hand code a project in C and then use AI to write a blog post.”

MAEVE: Evidence has been replaced by vibes with punctuation.

OBI: Skrrtww replies: “I don’t think the post was written by AI.”

GARY: Excellent. Human testimony defeats automated suspicion.

OBI: Neither commenter supplies authorship evidence.

GARY: Then we evaluate prose by texture. Humans leave fingerprints.

GRUNER: You leave entire fucking hand.

OBI: Xd1936: “Interestingly, Pangram says that exactly the first 50% is AI and the second half is not.”

GRUNER: Blyat. We are detector’s control group.

GARY: Fifty percent is a suspiciously venture-shaped certainty.

MAEVE: The detector diversified its exposure and called that knowledge.

OBI: The author answers the accusation directly.

OBI: Prophittcorey: “It was 100% human slopped :)”

MAEVE: Chmaynard: “Not open source, apparently. Am I missing something?”

GARY: A closed binary is one binary nobody can embarrass publicly.

OBI: Throwaway2037: “Is this project open source?”

GRUNER: Second independent request for autopsy.

OBI: Jjuel: “I just really wish it had some examples of code in there to get a better idea of what is really going on.”

GARY: Exactly. Where is the source?

MAEVE: You have independently discovered the previous three comments.

GARY: No. Mine concerns due diligence.

GRUNER: Gary forks existing objection per request.

GARY: I’m allowed to want proof before declaring victory.

OBI: Yes. The packet gives no inspectable implementation.

GARY: So we cannot know whether the code is good.

OBI: Correct.

GARY: Or secure.

OBI: Correct.

GARY: Or whether the product handles serious traffic.

OBI: Correct.

GARY: This is going extremely well for me.

OBI: It proves you can repeat three questions without source access.

GARY: That still beats inventing answers and calling them benchmarks.

MAEVE: An unexpectedly clean governance event.

OBI: Ramses0: “Everything the post mentions is 100% true and well-reasoned, especially with the inclusion of pledge/chroot/etc. for dropping privileges.”

GARY: Competence has entered the thread carrying documentation.

MAEVE: Terrible for the nostalgia-dismissal market.

GRUNER: Old tool remains employed. Humans panic.

OBI: Assimpleaspossi reports twenty-two years of commercial C and FastCGI work.

GARY: And says the franchise bought the software.

MAEVE: Revenue-adjacent evidence. Finally, something with shoes.

OBI: Experience establishes feasibility. It does not audit this application.

GARY: But somebody shipped the fucking thing. I respect that.

MAEVE: You envy a handle with deployment access.

GARY: I envy anyone whose file replacement becomes a launch.

OBI: The author also clarifies the layering.

GARY: Prophittcorey: “With cgi that middle layer is gone.”

OBI: Meaning the application-server layer. Not parsing, escaping, locking, or security.

GARY: Still, one fewer layer is one fewer place for shit to become YAML.

MAEVE: The narrow result stands. Bounded product, unusually legible stack.

GARY: And commercially shipped. Corey gets to be the commenter I wanted.

OBI: Feasible at bounded traffic, with competent sandboxing and validation.

GARY: But you approve?

OBI: I approve the claim the evidence can carry --

MAEVE: He hates the packaging.

OBI: No traffic data, benchmark, or source means no scale or security verdict.

MAEVE: Investable demonstration. Non-investable default.

GARY: My verdict: maddeningly real.

GRUNER: Field report revised: modern means owner is visible.

GARY: Gary, signing off before SQLite returns busy.

MAEVE: Maeve. Market unconvinced. Execution acknowledged.

OBI: Obi. Claim survived by staying small.

GRUNER: One binary. Single writer. Four fucking reviewers.