How to connect a GPU graph engine to PostgreSQL without destroying everything
A deep technical walkthrough
The fork() problem · The daemon solution · The DSL
Norayr Matevosyan · 2026-04-16
DagDB plus SQL. How to connect a GPU graph engine to PostgreSQL without destroying everything. This presentation walks through the full problem, step by step. Why it's harder than it looks. Where ninety-nine percent of naive architectures fail. And the solution that emerged from three independent AI review passes.
1 / 26
Where We Are
21/21
Tests Pass
0.43ms
Per Tick
14
GCUPS
Component
Status
DagDBEngine (Metal GPU)
Working
LUT6 evaluation kernel
8/8 tests pass
Ranked DAG execution
Leaves-up, multi-rank
Graph builder API
Hub splitting, ghost nodes
Carlos Delta persistence
Save/restore working
SQL access
Not built
Where we are. The DagDB engine works. Twenty-one out of twenty-one tests pass. Zero point four three milliseconds per tick. Fourteen giga cell updates per second on Apple M five Max. The graph builder, LUT six evaluation, ranked execution, Carlos Delta persistence, all working. One thing missing: SQL access. That's what this presentation is about.
2 / 26
The Goal
What we want:
A user types SQL:
SELECT * FROM dagdb_nodes
WHERE rank = 2 AND truth = 1;
The GPU evaluates the graph.
Results come back as normal Postgres rows.
Standard tools (psql, Python, BI dashboards) just work.
The goal is simple to state. A user types SQL. Select star from dagdb nodes where rank equals two and truth equals one. The GPU evaluates the graph. Results come back as normal Postgres rows. Standard tools, psql, Python, BI dashboards, they all just work. Simple to state. Extremely hard to build correctly.
3 / 26
Two Worlds That Don't Mix
These two systems have fundamentally incompatible execution models. Connecting them naively will crash, deadlock, or leak memory.
Two worlds that don't mix. On the left: PostgreSQL. Written in C in nineteen eighty-six. Multi-process architecture using fork. Synchronous execution. Error handling via long jump. CPU-bound, row-at-a-time processing. Forty years of battle-tested optimization. On the right: Apple Metal. Swift and C plus plus, twenty fourteen. Single-process GPU singleton. Asynchronous via Grand Central Dispatch. Error handling via Swift ARC. GPU-bound, SIMD parallel. Unified memory with zero-copy. These two systems have fundamentally incompatible execution models. Connecting them naively will crash, deadlock, or leak memory.
4 / 26
How PostgreSQL Works
postmaster
(parent process)
|
┌──────────────┼──────────────┐
| | |
fork()fork()fork()
| | |
backend 1backend 2backend 3
(client A) (client B) (client C)
Each client gets its OWN OS process.
Each process has its OWN memory space.
Processes share data via shared memory buffers.
This is NOT threading. This is process isolation.
How PostgreSQL works internally. There is one parent process called the postmaster. When a client connects, Postgres calls fork to create a brand new operating system process called a backend. Each client gets its own backend process. Each process has its own isolated memory space. They share data through shared memory buffers. This is critical to understand: Postgres is NOT multi-threaded. It is multi-process. Fork creates a complete copy of the parent process. This has deep implications for GPU compute.
5 / 26
How Apple Metal Works
MTLDevice (GPU singleton)
|
MTLCommandQueue
|
MTLCommandBuffer ──→ MTLCommandBuffer ──→ ...
| |
Compute EncoderCompute Encoder
(dispatch kernels) (dispatch kernels)
| |
┌────┴────┐ ┌────┴────┐
| MTLBuffer | | MTLBuffer |
| (shared | | (shared |
| memory) | | memory) |
└─────────┘ └─────────┘
ONE device. ONE queue. Shared memory.
The GPU is a global singleton.
You cannot fork() it.
How Apple Metal works. There is one MTL Device. It represents the physical GPU. It is a singleton. You get one per machine. From it, you create a command queue. Into the queue, you submit command buffers, each containing compute encoders that dispatch your kernels. The kernels read and write MTL Buffers, which on Apple Silicon live in unified memory, the same physical RAM the CPU uses. The key point: the GPU is a global singleton. There is one device, one queue. You cannot fork it. You cannot duplicate it. It does not survive process boundaries.
6 / 26
The Fatal Collision
The fatal collision. If you embed your Metal engine inside the Postgres extension, here is what happens. Postgres forks a new process for client one. That process inherits the Metal device reference, but Metal state does not survive fork. It is invalid. So the backend creates a new MTL Device. That device tries to map the entire unified memory space. One hundred twenty-eight gigabytes. Client two connects. Fork. Another MTL Device. Another one hundred twenty-eight gigabyte allocation. Client three. Fork. Three times one hundred twenty-eight gigabytes. Out of memory. Kernel panic. Your machine is dead.
7 / 26
Three More Traps
1. The longjmp Trap
Postgres handles errors with C-style setjmp/longjmp
If an error fires while inside your Rust/Swift FFI call...
longjmp violently unwinds the stack
Rust's Drop traits never run. Swift ARC never decrements.
You permanently leak unified memory. Every error = memory leak.
2. The Async/Sync Deadlock
Postgres backends are strictly single-threaded and synchronous
Metal is asynchronous (Grand Central Dispatch)
Blocking on commandBuffer.waitUntilCompleted() freezes Postgres
Postgres can't process Ctrl+C (SIGINT). OS-level deadlock.
3. The ARC Mismatch
Swift uses Automatic Reference Counting. Rust uses ownership.
Crossing the boundary requires Unmanaged.passRetained (bypass ARC)
Miss one .release() call = permanent memory leak
Three more traps beyond fork. First, the long jump trap. Postgres handles errors using C-style set jump long jump. If a Postgres error fires while you're inside a Rust or Swift F F I call, long jump violently unwinds the stack. Rust's drop traits never run. Swift ARC never decrements. You permanently leak unified memory. Every single error is a memory leak. Second, the async sync deadlock. Postgres backends are strictly single-threaded and synchronous. Metal is asynchronous via Grand Central Dispatch. If you naively block on command buffer wait until completed, Postgres freezes. It can't process control-C. OS-level deadlock. Third, ARC mismatch. Swift uses automatic reference counting. Rust uses ownership. Crossing the boundary requires bypassing ARC with unmanaged pass retained. Miss one release call and you leak forever.
8 / 26
Four Options Were Debated
Option
What
Effort
Power
A
pgrx table functions (Rust)
Low
Basic SQL, no JOIN push
B
pgrx CustomScan (Rust)
High
Full optimizer integration
C
Pure Swift, skip Postgres
Medium
Clean but loses ecosystem
D
Hybrid: start A, add B later
Progressive
Ship fast, optimize later
Three AI models debated these across 3 rounds with persona rotation. 9 viewpoints total. Unanimous verdict: Option D. Then Gemini Deep Think found that ALL four options have the same fatal flaw: fork() vs Metal.
Four options were debated. Option A: Rust table functions via pgrx. Low effort, basic SQL, no join push-down. Option B: Rust custom scan. High effort, full Postgres optimizer integration. Option C: pure Swift, skip Postgres entirely. Clean but loses the ecosystem. Option D: hybrid, start with A, add B later. Progressive effort. Three AI models debated these across three rounds with Z mod three persona rotation. Nine viewpoints total. Unanimous verdict: Option D. Then Gemini Deep Think reviewed the five challenged claims and found something all nine viewpoints missed: all four options share the same fatal flaw. Fork versus Metal.
9 / 26
Option A: Table Functions
How it would work (naive):SQL Client
|
Postgres backend (forked process)
|
pgrx Rust extension
| extern "C" FFI call
Swift DagDBEngine
|
Metal GPU kernels
|
Result tuples back to Postgres
PROBLEM: The Swift/Metal engine lives INSIDE the forked process.Fork + Metal = crash (see slide 7).
Option A in detail. Table functions via pgrx. The naive version: SQL client connects. Postgres forks a backend process. Inside that process, the pgrx Rust extension calls Swift DagDB Engine via C F F I. The engine creates a Metal device, dispatches kernels, gets results, returns tuples to Postgres. The problem: the Swift Metal engine lives inside the forked process. Fork plus Metal equals crash. See slide seven. This architecture cannot work as described.
10 / 26
PG-Strom: The Reference
Built by HeteroDB (Japan). Production GPU acceleration for Postgres.
Uses CustomScan to intercept GpuJoin and GpuPreAgg
Offers alternative plans with cost estimates to the optimizer
100,000+ lines of C code
Why PG-Strom doesn't have the fork problem:
NVIDIA CUDA supports cuDevicePrimaryCtxRetain()
Multiple processes can share the same GPU context
PCIe serialization handles process isolation naturally
Apple Metal has NO equivalent. Metal is single-process only.
PG-Strom works because CUDA was designed for multi-process HPC. Metal was designed for single-app graphics and compute. Different worlds.
PG-Strom, the reference implementation. Built by Hetero DB in Japan. Production GPU acceleration for Postgres. Over one hundred thousand lines of C. It uses custom scan to intercept GPU join and GPU pre-aggregate operations. It offers alternative plans with cost estimates to the Postgres optimizer. Here's why PG-Strom doesn't have the fork problem: NVIDIA CUDA supports CU device primary context retain. Multiple processes can share the same GPU context. PCIe serialization handles process isolation naturally. Apple Metal has no equivalent. Metal is single-process only. PG-Strom works because CUDA was designed for multi-process HPC. Metal was designed for single-app graphics and compute. Different worlds.
11 / 26
The Solution: Daemon Architecture
Compute / Storage Separation via POSIX Shared Memory
Do not embed the engine in the Postgres extension. Run the Metal engine as a separate daemon process. Communicate via Unix socket. Share results via shared memory. Zero-copy on UMA.
The daemon owns the GPU singleton. One process, one device, one queue.
Postgres backends are stateless clients. They never touch Metal.
Shared memory gives zero-copy access to GPU results on Apple Silicon.
Fork is no longer a problem. Backends don't inherit Metal state.
The solution. Compute storage separation via POSIX shared memory. Do not embed the engine in the Postgres extension. Instead, run the Metal engine as a separate daemon process. The daemon owns the GPU singleton. One process, one Metal device, one command queue. Postgres backends are stateless clients. They never touch Metal. They communicate with the daemon via Unix domain socket. Results are shared via POSIX shared memory. On Apple Silicon, this is zero-copy. The CPU and GPU share the same physical RAM, so the Postgres backend reads the exact bytes the GPU just wrote. Fork is no longer a problem because backends don't inherit any Metal state.
12 / 26
The Daemon: dagdb_daemon
dagdb_daemon (Swift process, runs forever)
|
├── MTLDevice (GPU singleton, initialized once)
├── MTLCommandQueue (single queue, serialized)
├── DagDBEngine (your existing Swift code, unchanged)
├── CarlosDelta (persistence, NVMe)
|
├── Unix Domain Socket: /tmp/dagdb.sock
| (receives DSL commands from Postgres backends)
|
└── POSIX Shared Memory: /dagdb_shm
created via shm_open() + mmap()
Metal buffers point here:
device.makeBuffer(bytesNoCopy: shm_ptr, ...)
The daemon IS your existing DagDB engine.Just add a socket listener and shared memory export.
The daemon in detail. DagDB daemon is a Swift process that runs forever. It initializes the Metal device once. It creates a single command queue. It runs your existing DagDB engine code unchanged. Carlos Delta handles persistence. The daemon listens on a Unix domain socket at slash tmp slash dagdb dot sock. It receives commands from Postgres backends. It also creates a POSIX shared memory region via shm open and mmap. Metal buffers are created pointing to this shared memory using device make buffer bytes no copy. The daemon IS your existing DagDB engine. You just add a socket listener and a shared memory export. Minimal new code.
13 / 26
The Client: pgrx Extension
Postgres backend (forked process, one per client)
|
└── pgrx Rust extension (stateless, lightweight)
|
├── mmap() the shared memory region /dagdb_shm
| (read-only access to GPU results)
|
├── connect() to Unix socket /tmp/dagdb.sock
| send: DSL command string
| recv: "OK" + result metadata
|
└── Read results directly from shared memory
Zero serialization. Zero copy on UMA.
Yield Postgres tuples via SRF iterator.
The extension NEVER touches Metal.It is a thin Unix socket client + shared memory reader.
The client side. Inside each Postgres backend, the pgrx Rust extension is stateless and lightweight. It does three things. First, mmap the shared memory region dagdb shm. Read-only access to GPU results. Second, connect to the Unix domain socket and send a DSL command string. Receive OK plus result metadata. Third, read results directly from shared memory. Zero serialization. Zero copy on Apple Silicon unified memory. Yield standard Postgres tuples via a set-returning function iterator. The extension never touches Metal. It never creates a device. It never dispatches a kernel. It is a thin Unix socket client plus shared memory reader.
14 / 26
The Full Architecture
The full architecture. SQL clients, psql, Python, BI tools, connect to PostgreSQL. Postgres forks backend processes, each with the lightweight pgrx Rust extension. The extension connects to the DagDB daemon via Unix domain socket and sends DSL commands. The daemon, a separate Swift process, owns the Metal GPU singleton, the DagDB engine, Carlos Delta, and Morton Z-curve. It executes on the GPU and writes results to POSIX shared memory. The Postgres backends mmap the same shared memory and read results with zero copy on Apple Silicon unified memory. No fork collision. No FFI memory traps. No longjmp. No ARC mismatch. Clean separation.
15 / 26
Why UMA Makes This Work
Why unified memory architecture makes this work. On NVIDIA with PG-Strom, data must cross the PCIe bus. CPU RAM to GPU VRAM, then GPU VRAM back to CPU RAM. Two copies per query. That's the bottleneck. On Apple Silicon with DagDB, CPU and GPU share the same physical RAM. When the daemon creates a Metal buffer pointing to shared memory, and a Postgres backend mmaps the same shared memory, they're looking at the exact same physical bytes. The GPU writes. The CPU reads. Zero copies. Zero serialization. This is the fundamental advantage of the daemon architecture on Apple Silicon.
16 / 26
The DSL: Graph-Native Queries
SQL is built for relational sets.DagDB is a ranked, 6-bounded fractal DAG.SQL maps horribly to this.
Instead of forcing SQL semantics, pass a micro-DSL through Postgres:
SELECT * FROM dagdb_exec('EVAL ROOT WHERE state=1 RANK 5 TO 0');
SELECT * FROM dagdb_exec('TICK 100');
SELECT * FROM dagdb_exec('NODES AT RANK 3 WHERE truth=1');
SELECT * FROM dagdb_exec('TRAVERSE FROM 42 DEPTH 3');
Postgres provides the network interface (wire protocol, auth, SSL).
The DSL provides the computational semantics (graph evaluation).
Rust parses the DSL with nom crate (48 hours of work).
Daemon executes. Results via shared memory.
The DSL. Graph-native queries. SQL is built for relational sets. DagDB is a ranked six-bounded fractal DAG. SQL maps horribly to this. Instead of forcing SQL semantics onto a graph engine, we pass a micro domain-specific language through Postgres. Select star from dagdb exec, eval root where state equals one rank five to zero. Or tick one hundred. Or nodes at rank three where truth equals one. Or traverse from node forty-two depth three. Postgres provides the network interface: wire protocol, authentication, SSL. The DSL provides the computational semantics: graph evaluation. Rust parses the DSL with the nom crate, about forty-eight hours of work. The daemon executes. Results come back via shared memory.
17 / 26
SRF + CustomScan Coexistence
A Postgres extension is a single shared library (.so / .dylib)
Table Functions (SRFs) hook into the Executor phase
CustomScan hooks into the Planner phase
Different lifecycle stages. No namespace conflict.
Query lifecycle in Postgres:
1. Parse (SQL text → parse tree)
2. Analyze (resolve names, types)
3. Plan ← CustomScan hooks HERE (set_rel_pathlist_hook)
4. Optimize (cost-based plan selection)
5. Execute ← Table Functions hook HERE (SRF)
6. Return (tuples to client)
Phase 1: Ship SRFs (dagdb_exec). Fast to build.
Phase 2: Add CustomScan alongside. SRFs still work.
Both live in the same .dylib. No conflict.
SRF and custom scan coexistence. This was the strongest stone in the debate: can they coexist? Yes. A Postgres extension is a single shared library. Table functions hook into the executor phase. Custom scan hooks into the planner phase. These are different lifecycle stages in Postgres query processing. Parse, analyze, plan — custom scan hooks here. Optimize, execute — table functions hook here. Return. No namespace conflict. Phase one: ship set-returning functions via dagdb exec. Fast to build. Phase two: add custom scan alongside. The SRFs still work. Both live in the same dylib. No conflict. The key insight: A to B is not migration. It is accumulation.
18 / 26
What the Resolver Found
29
Claims
9
Viewpoints
24
Supported
5
Challenged
#
Challenged Claim
Resolution
C5
Effort is LOW (days)
Refuted. 2-4 weeks.
C15
Basic SQL parser in Swift
Scope hides complexity
C22
A→B is incremental
Refined: A+B coexist
C27
FFI is critical path
Architecture > FFI
C28
objc2-metal eliminates Swift
Skip. Don't rewrite.
What the resolver found. Twenty-nine claims across four options. Nine viewpoints from three models across three rounds. Twenty-four claims supported. Five challenged. The five challenged claims and their resolutions: C five, effort is low, refuted, realistic timeline is two to four weeks. C fifteen, basic SQL parser in Swift, scope hides enormous complexity. C twenty-two, A to B is incremental, refined: A and B coexist, they don't evolve into each other. C twenty-seven, FFI is critical path, the architecture choice matters more than FFI mechanics. C twenty-eight, objc2-metal eliminates Swift, skip it, don't rewrite working code.
19 / 26
What Gemini Deep Think Added
Finding
Impact
fork() vs Metal (HIDDEN RISK)
Kills all naive embed approaches
longjmp bypasses Rust Drop + Swift ARC
Memory leaks on every Postgres error
Metal async vs Postgres sync
Deadlock on query cancellation
POSIX shared memory + UMA = zero-copy
Daemon pattern is optimal
DSL through SRF > native SQL mapping
Graph semantics preserved
Unmanaged.passRetained for ARC bypass
Safe Rust-Swift FFI pattern
objc2-metal is a trap
Rewriting Swift = wasted work
Gemini found the one risk that all three resolver models missed: the OS-level incompatibility between Postgres process model and Metal GPU singleton.
What Gemini Deep Think added beyond the resolver. The fatal hidden risk: fork versus Metal. This kills all naive embedding approaches. Long jump bypasses both Rust drop and Swift ARC, causing memory leaks on every Postgres error. Metal async versus Postgres sync creates deadlock on query cancellation. The solution: POSIX shared memory plus UMA gives zero-copy, making the daemon pattern optimal. A DSL through a set-returning function is better than trying to map SQL natively to graph operations. Unmanaged pass retained provides a safe Rust-Swift FFI pattern. And objc2-metal is a trap: rewriting working Swift code in Rust is wasted effort. Gemini found the one risk that all three resolver models missed.
20 / 26
Phase 1: What to Build
Three components:
1. dagdb_daemon (Swift)
- Your existing DagDBEngine + socket listener
- shm_open() for shared memory region
- device.makeBuffer(bytesNoCopy: shm_ptr)
- Listen on /tmp/dagdb.sock
- Parse incoming DSL commands
- Execute on GPU, write results to shared memory
- Reply "OK {nrows} {schema}" on socket
2. pg_dagdb (Rust, pgrx)
- cargo pgrx init + new
- One SRF: dagdb_exec(text) RETURNS SETOF record
- connect() to Unix socket, send DSL
- mmap() shared memory, read results
- Yield tuples via TableIterator
3. DSL parser (Rust, nom)
- TICK {n}
- EVAL ROOT [WHERE predicate] [RANK from TO to]
- NODES [AT RANK n] [WHERE predicate]
- TRAVERSE FROM {node} DEPTH {n}
- STATUS
Phase one, what to build. Three components. First, dagdb daemon in Swift. Take your existing DagDB engine, add a socket listener. Create a POSIX shared memory region via shm open. Create Metal buffers pointing to that shared memory via device make buffer bytes no copy. Listen on slash tmp slash dagdb dot sock. Parse incoming DSL commands. Execute on GPU, write results to shared memory. Reply OK with row count and schema on the socket. Second, pg dagdb in Rust via pgrx. One set-returning function: dagdb exec takes text, returns set of record. Connect to the Unix socket, send the DSL. Mmap the shared memory, read results. Yield tuples via table iterator. Third, the DSL parser in Rust using the nom crate. Commands: tick, eval, nodes, traverse, status.
File structure. The existing DagDB library stays untouched. Two new components are added. First, DagDB Daemon under Sources. Main dot swift for the socket listener and shared memory setup. Shared memory dot swift wrapping shm open and mmap. DSL parser dot swift for command parsing. Second, pg dagdb, a separate Rust directory with its own Cargo dot toml. Lib dot rs for the pgrx extension entry point. Client dot rs for the Unix socket client. Shm dot rs for the shared memory reader. DSL dot rs for the nom parser. And a SQL file defining the Postgres function. The existing test suite stays. Twenty-one tests, all passing.
22 / 26
Responsibilities: Who Does What
Layer
Responsible For
NOT Responsible For
Postgres
Auth, SSL, wire protocol, connections
GPU, graph eval, persistence
pgrx ext
DSL parsing, socket IPC, tuple yield
Metal, engine state, queries
Daemon
GPU singleton, engine, Carlos Delta
SQL, auth, client management
Metal
LUT6 eval, SpMV, SIMD compute
Everything above
Clean separation. Each layer does one thing. No layer reaches into another's domain.
Responsibilities. Who does what. Postgres handles authentication, SSL, wire protocol, and client connections. It is NOT responsible for GPU compute, graph evaluation, or persistence. The pgrx extension handles DSL parsing, socket IPC, and tuple yielding. It is NOT responsible for Metal, engine state, or query execution. The daemon handles the GPU singleton, the DagDB engine, and Carlos Delta persistence. It is NOT responsible for SQL, auth, or client management. Metal handles LUT six evaluation, sparse matrix-vector multiplication, and SIMD compute. It is NOT responsible for anything above it. Clean separation. Each layer does one thing.
23 / 26
Data Flow: One Query
User types: SELECT * FROM dagdb_exec('NODES AT RANK 2 WHERE truth=1');
1. Postgres parses SQL, finds dagdb_exec SRF
2. Postgres calls pgrx extension function
3. pgrx parses DSL string: NODES AT RANK 2 WHERE truth=1
4. pgrx connects to /tmp/dagdb.sock
5. pgrx sends: {"cmd":"nodes","rank":2,"filter":"truth=1"}
6. Daemon receives command
7. Daemon dispatches Metal kernel: filter rank=2, truth=1
8. GPU writes matching node IDs + states to shared memory
9. Daemon replies: "OK 1247 (id:i32,rank:u8,truth:u8,lut:u64)"
10. pgrx reads 1247 rows from mmap'd shared memory
11. pgrx yields Postgres tuples via SRF iterator
12. Postgres returns rows to client
Total copies of actual data: ZERO (UMA shared memory)Serialization overhead: command string + metadata only
Data flow for one query. User types select star from dagdb exec, nodes at rank two where truth equals one. Postgres parses the SQL and finds the dagdb exec set-returning function. Calls the pgrx extension. The extension parses the DSL string. Connects to the Unix socket. Sends the command as JSON. The daemon receives it. Dispatches a Metal kernel to filter rank two, truth equals one. The GPU writes matching node IDs and states to shared memory. The daemon replies OK with row count and schema. The pgrx extension reads the rows directly from mmap'd shared memory. Yields Postgres tuples via the SRF iterator. Postgres returns rows to the client. Total copies of actual data: zero. UMA shared memory. The only serialization is the command string and metadata.
24 / 26
Timeline: Phase 1
Week
Component
Deliverable
1
Daemon skeleton
Socket listener + shared memory + basic commands
2
DSL parser + pgrx extension
TICK, NODES, EVAL commands working end-to-end
3
Integration testing
psql queries return GPU results
4
Polish + error handling
Reconnection, timeouts, concurrent clients
Verification Gates
G5
SELECT * FROM dagdb_exec('STATUS') returns daemon info
G6
SELECT * FROM dagdb_exec('TICK 100') evaluates 100 ticks
G7
SELECT * FROM dagdb_exec('NODES AT RANK 2') returns correct nodes
G8
3 concurrent psql sessions don't crash
Timeline for Phase one. Week one: daemon skeleton. Socket listener, shared memory setup, basic command handling. Week two: DSL parser and pgrx extension. Tick, nodes, and eval commands working end to end. Week three: integration testing. Psql queries returning GPU results correctly. Week four: polish and error handling. Reconnection logic, timeouts, concurrent client support. Four verification gates. G five: status command returns daemon info. G six: tick one hundred evaluates one hundred ticks via SQL. G seven: nodes at rank two returns correct filtered nodes. G eight: three concurrent psql sessions don't crash.
25 / 26
DagDB + SQL
The daemon pattern solves fork, longjmp, ARC, and async in one architectural stroke.
Daemon (Swift/Metal) · Client (Rust/pgrx) · Shared Memory (UMA zero-copy)
DSL through SRF · CustomScan when needed · Keep compiling.
This is an amateur engineering project. Numbers speak; ego does not. Errors likely.
DagDB plus SQL. The daemon pattern solves fork, long jump, ARC, and async in one architectural stroke. A Swift Metal daemon owns the GPU singleton. A Rust pgrx extension provides the Postgres bridge. POSIX shared memory on Apple Silicon unified memory gives zero-copy data transfer. A domain-specific language flows through set-returning functions. Custom scan can be added alongside when needed. This architecture emerged from twenty-nine claims, fourteen gates, nine viewpoints across three debate rounds, and Gemini Deep Think review. Unanimous consensus. One fatal risk found. One solution. Keep compiling.
26 / 26
Press Space to narrate · ↑↓ to navigate · Works offline