Tiknix runs on PHP and defaults to SQLite. Both choices attract eye-rolls from people who haven't looked at either in a decade. Both are, on the merits, extremely good calls for the kind of software most people are actually building.
The case for PHP, made in 2026
PHP's defining property is that the deployment story is already solved everywhere. A PHP application is a directory of files behind a web server. There is no build step, no process supervisor, no container orchestration, no long-lived runtime that leaks memory across requests. You copy the files up; the next request runs the new code.
That model has a second, underrated property: request isolation by default. Each HTTP request gets a fresh interpreter state and tears it down when it finishes. A memory leak in one request cannot degrade the next one. A crash affects one user. Whole classes of bugs that long-running application servers spend real engineering effort on — connection pool exhaustion, stale globals, event-loop starvation — simply do not have anywhere to live.
Modern PHP is also not the language of its reputation. Tiknix runs on PHP 8.5
— the composer floor is >=8.1, but the deployed runtime is current, and staying
current is the point. That means typed properties, enums, readonly properties, first-class
callables, constructor promotion, match expressions, and named arguments. The code in
lib/ reads like any other typed, modern server language:
public static function check(
string $action,
int $maxAttempts = 5,
int $windowSeconds = 300,
?string $identifier = null
): bool {
// lib/RateLimiter.php
}
And the ecosystem behind it is mature in the boring way that matters: Composer for dependencies, PSR standards for interoperability, Monolog for logging, PHPUnit for tests. Tiknix uses all of them rather than inventing house equivalents.
Where PHP genuinely costs you
Long-lived connections and background work are the honest weak spots. WebSockets, streaming, and persistent worker processes want a different runtime shape. Tiknix does not pretend otherwise — the AI Builder's terminal and chat channels run through separate Node and PHP bridge processes on local ports, and the web tier proxies to them. That is the right answer, and it's worth knowing up front that "everything is a request" has a boundary.
The case for SQLite
SQLite is the most widely deployed database engine in existence — it is in every phone, every browser, most desktop applications, and a great deal of embedded hardware. Its test suite is famously exhaustive. Its file format is a documented, forward-compatible standard that the authors have committed to supporting into the 2050s. It is, by any reasonable measure, some of the most thoroughly validated software you will ever depend on.
What that means practically, on a Tiknix install:
- No database server. No port, no daemon, no credentials, no separate host to secure or patch. One less service that can be down.
- Backups are
cp. Your entire application state is one file atdatabase/tiknix.db. Copying it is a backup. Copying it back is a restore. (Usesqlite3 .backupor the backup API for a consistent copy while writes are in flight.) - Environments are trivially reproducible. A workspace clone is a file copy. This is exactly how
lib/WorkspaceManager.phpprovisions isolated instances for AI Builder tasks: fresh SQLite database, fresh config, fully independent. - Reads are extremely fast. No network hop, no serialization across a socket. An in-process query against a warm page cache is measured in microseconds.
The write-concurrency question, answered directly
The standard objection is write concurrency, and it is a real constraint: SQLite serializes writers. One write transaction proceeds at a time; others wait. In WAL mode, readers do not block writers and writers do not block readers, which removes most of the practical pain — but the single-writer rule stands.
The useful question is not "is that a limitation" (it is) but "does it bind on your workload." For an internal tool, a team dashboard, a customer portal, a booking system, a CRM, or a SaaS in its first few thousand users, write volume is nowhere near the ceiling. Read-heavy applications with modest write rates run on SQLite comfortably for years.
And if you outgrow it, you are not trapped. Tiknix's data layer is RedBeanPHP, which speaks SQLite, MySQL, MariaDB, and PostgreSQL through the same bean API. Switching is a config change plus a data migration:
; conf/config.ini — SQLite (default)
[database]
type = "sqlite"
path = "database/tiknix.db"
; conf/config.ini — MySQL
[database]
type = "mysql"
host = "localhost"
name = "tiknix"
user = "tiknix"
pass = "your_password"
Your controllers do not change. That optionality is the real argument: start on the simplest thing that works, with a known exit if the simple thing stops working.
SQLite is not a museum piece
The strongest argument against "SQLite is a toy" is not a rebuttal — it is the ecosystem that has grown around it in the last few years. Two projects are worth knowing about, because they change what the ceiling looks like.
Turso: SQLite, rewritten and scaled out
Turso is a ground-up rewrite of SQLite in Rust with an async-first architecture, staying backwards compatible with the file format and SQL you already use. It comes in two shapes: an embedded engine (currently beta) that runs offline, in a browser, or on a device, and Turso Cloud (production ready), which hosts unlimited SQLite databases over the network or syncs them down to your own devices.
Three things there matter for the argument in this article:
- Databases are files, not processes. Turso's own framing — "no cold starts, no scale-to-zero, no wake-up penalty." That is the same property that makes local SQLite pleasant, preserved at hosted scale.
- Massive multi-tenancy. Their pitch is scaling to billions of databases. A database-per-tenant architecture is absurd with Postgres and natural with SQLite — and that changes how you might isolate customers.
- Concurrent writes are being worked on directly. Turso is running early access for concurrent writes in the cloud product. The single-writer constraint discussed above is not a law of nature; it is an implementation property that people are actively attacking.
The relevance to a Tiknix install is optionality. You start on a local SQLite file with zero operational overhead. If you outgrow it, "move to Postgres" is one exit — and "move to a hosted, replicated, SQLite-compatible engine" is now another, one that does not require rewriting your queries at all.
sqlite-vector: embedded databases are moving toward AI, not away from it
sqlite-vector is a cross-platform SQLite extension for approximate nearest-neighbor search. What makes it notable is how little ceremony it requires: vectors are stored as ordinary BLOBs in ordinary tables — no virtual tables, no preprocessing step, no separate index structure to keep in sync.
-- load the extension, then it's just SQL
SELECT load_extension('./vector');
SELECT vector_init(...);
SELECT vector_quantize(...);
SELECT vector_quantize_scan(...); -- or vector_full_scan()
It supports Float32, Float16, BFloat16, Int8, UInt8, and 1-bit vectors, with L2, squared L2, L1, cosine, dot product, and Hamming distance. Its TurboQuant quantization does 2/3/4-bit compression with SIMD-accelerated scanning; the project's own benchmarks on 1M 768-dimension vectors report roughly 14.9× speedup at 0.84 recall@10 for 4-bit and 38.3× at 0.48 recall@10 for 2-bit, with storage down to about 7–13% of raw Float32. It runs on iOS, Android, Windows, Linux, macOS, and WASM.
Read those numbers as the project's benchmarks on their hardware and workload, and note the recall column honestly: 2-bit is dramatically faster and loses about half its top-10 accuracy. Quantization is a knob, not a free win.
The broader point stands regardless of the numbers: semantic search and RAG are becoming things an embedded database does, not things that require a separate vector service. Turso ships native vector search in-engine — "no extensions required" — and sqlite-vector brings it to stock SQLite. For an application built around AI features, "my database is a file" and "my database does similarity search" are no longer opposing choices.
Why this substrate suits AI-assisted development specifically
Three properties compound when an agent is writing the code:
- The feedback loop has no build step. An agent edits a file and the very next request executes it. There is no compile, no bundle, no restart, no cache to bust. Iteration latency is close to zero, which matters a great deal when the loop runs hundreds of times.
- Training data density is enormous. PHP and SQL are among the most represented languages in any model's training corpus, and the patterns are long-stable. A model writing PHP 8 with PDO-backed queries is operating deep inside familiar territory rather than extrapolating from a handful of examples.
- State is a file, so rollback is a file operation. Snapshot the database and the working tree before a risky change; restore both if it goes wrong. Tiknix's checkpoint and rollback controls in the AI Builder rest directly on this. Reversibility is what makes it reasonable to let an agent try something.
The honest version of the pitch
PHP and SQLite are not chosen here because they are trendy, and not out of nostalgia. They are chosen because they minimize the number of moving parts between "I wrote a line of code" and "a user can see it." Fewer moving parts means fewer failure modes, faster loops, cheaper hosting, and a system a single person — or a single person plus an agent — can hold in their head.
- SQLite serializes writes. Enable WAL mode, keep transactions short, and measure before assuming you have a problem. If sustained concurrent writes are core to your workload, start on Postgres or MySQL — the switch is supported, and doing it early is cheaper than doing it later. Turso's concurrent-write work is promising and is early access, not something to plan a launch around today.
- Turso Database is beta; Turso Cloud is not. The Rust rewrite is explicitly labeled beta by its authors, while the hosted product is marked production ready. Pick the one whose status matches your risk tolerance, and do not conflate the two.
- sqlite-vector's license needs reading before you ship. Free for open-source projects under OSI-approved licenses, governed by the Elastic License 2.0 otherwise, and production use requires a commercial license from SQLite Cloud, Inc. That is a business decision, not a footnote — check it before it is load-bearing.
- Quantization trades recall for speed. The 38× number comes with 0.48 recall@10. Benchmark against your own data and decide what accuracy your feature actually needs.
- Not every host is equal. SQLite on network storage (NFS, some container volume drivers) can misbehave around file locking. Keep the database file on local disk.
- PHP wants a real deployment discipline anyway. "Just copy the files" is a strength until two people copy different files. Deploy from Git, not from your laptop.
- Long-lived connections need a second process. WebSockets and background workers are not a request/response fit. Tiknix runs them as separate local services and proxies — plan for that shape rather than fighting it.
- APCu is optional but assumed. The caching layer degrades gracefully without it, but you lose most of the performance story. Install it — see the caching article.