S4E394 — A Modern Web App in C
October 13, 2026 · 13 min
Show notes
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.
