Frameworks like Node.js lack the primitives for safe applications. Postgres has had them for decades. It should be at the core of our designs. Almost a decade after this paper's publication, concurrent bugs are still plaguing applications. Even seasoned programmers get caught. (And new coding assistants like Claude Code also struggle.) That's because it takes very little to create a concurrency bug: 2 concurrent actions... What's really sad is that these problems have been solved by databases like Postgres decades ago. We need libraries that bring transactional guarantees into application code: steps that always run at-least-once or exactly-once, in order, backed by the database. Look at the findings of the paper (consistent with other studies). The root causes of bugs in Node.js: - 65% atomicity violation (no transactions in Node.js...) - 35% order violation (no synchronization primitives in Node.js...) Note that 40% of bugs came from interacting with external APIs. For example, check figure 4 in the paper: this is a typical example of un-orchestrated calls to an external API leading to data losses. When this happens, teams often reach for heavy orchestration frameworks like Airflow or Temporal, even though a simple Postgres-backed SAGA could suffice. The paper also finds that 50% of concurrency bugs are caused by API mis-use. i.e., people get fooled by async/await. So, what do we do? Node.js is very popular and for good reasons: javascript/typescript are much more approachable than traditional backend languages like C# or Java. Many devs enjoy using the same language for both frontend and backend. But twisting the framework to make concurrent programs safe is really, really hard in Node.js. One approach is to bring ACID properties to the application by embedding a RDBMS-backed library to the framework. For example, if you provide a "step" abstraction, with automatic ID generation and checkpointing, you can ensure that each step is executed at-least-once or exactly-once and that they order is always the same. Happy to chat more about that idea :) #postgres #nodejs
This is total nonsense. One can always write one's own synchronization libraries. Relying on a programming language to provide synchronization primitives is infantile. To do so implies applications written in different languages would not be able to access shared data. Resource management must be language agnostic and language independent. This is what operating systems do. 😊
You grossly misunderstand Postgres architecture. Any database server that uses vanilla file systems to store and manage its data is inherently unreliable. This is something the database industry has learned more than 4 decades ago. POSIX file systems and POSIX block devices provide no atomicity guarantees. This is the reason why enterprise-grade databases such as Oracle, Informix, DB2 or Sybase rely on raw IO or use the Veritas Database Editions. It is gross professional malpractice for database servers to rely on vanilla POSIX file systems. 😊
"Look at the findings of the paper (consistent with other studies). The root causes of bugs in Node.js: - 65% atomicity violation (no transactions in Node.js...) - 35% order violation (no synchronization primitives in Node.js...)" This is a completely absurd argument! There are no transactions and no synchronization primitives in any major programming languages! Not C, not C++, not Java, not Pascal, not Fortran, etc... Atomicity violations, data races, synchronization errors, etc., are the result of incorrect designs. Programming languages cannot provide enough guardrails to protect software developers from their own incompetence, any more than ABS can prevent automobiles from crashing! 😊
Founding Engineer @ DBOS | Help you build reliable software | Leading Workflow Orchestration Technology
2moLink to the paper: http://www.tcse.cn/~wsdou/papers/2017-ase-nodecb.pdf