<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/your-executable-is-a-sqlite-database-xpecfwhbu" -->

---
title: Your executable is a SQLite database | daily.dev
description: A prototype called SELF (Structured Executable &amp; Linkable Format) replaces the ELF binary format with an actual SQLite database file: the executable itself is...
canonical: https://daily.dev/posts/your-executable-is-a-sqlite-database-xpecfwhbu
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Your executable is a SQLite database | daily.dev
og:description: A prototype called SELF (Structured Executable &amp; Linkable Format) replaces the ELF binary format with an actual SQLite database file: the executable itself is...
og:url: https://daily.dev/posts/your-executable-is-a-sqlite-database-xpecfwhbu
og:image: https://api.daily.dev/og/posts/xPeCfWhbU.png
og:image:alt: Your executable is a SQLite database
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Your executable is a SQLite database

**[Farid Zakaria’s Blog](https://daily.dev/sources/fzakaria)** · 14 min read · 28 upvotes · 2 comments

## Summary

A prototype called SELF (Structured Executable & Linkable Format) replaces the ELF binary format with an actual SQLite database file: the executable itself is a .sqlite file, queryable and modifiable via SQL. The author frames ELF as a hand-rolled database (string tables as interning, hash sections as indexes, section headers as a schema table) and shows how stripping symbols becomes a DELETE+VACUUM transaction, patching becomes an UPDATE, and ldd becomes a JOIN. Using binfmt_misc and a custom interpreter (self-exec), SQLite-backed binaries run natively on NixOS. Dynamic linking is implemented two ways: via glibc's rtld-audit interface backed by SQL queries, and via a from-scratch SQL-based dynamic linker (self-ld). Benchmarks show a single stripped binary lands within 1% of ELF size, while packing an entire userland (723 executables, 400 libraries) into one database yields 611.9 MiB versus 644.4 MiB of separate ELF files, due to natural deduplication. Runtime overhead includes a fixed ~5ms SQLite startup cost and lack of shared mmap'd text pages between processes. The project and tooling (elf2self, self scan, self closure) are open source on GitHub.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://fzakaria.com/2026/08/23/your-executable-is-a-sqlite-database>

## Questions this post answers

### How much bigger is a SQLite-based executable format compared to a stripped ELF binary?

A stripped SELF (SQLite-based executable) file for coreutils is 1,794,048 bytes versus 1,768,632 bytes for the equivalent ELF binary, a difference within 1%. The overhead mostly comes from SQLite's b-tree structures and optional metadata tables used for debugging and tooling, which can be deleted in a transaction similar to running strip on an ELF file.

_Anyone weighing binary format trade-offs for size can track experiments like SQLite-as-executable through daily.dev._

### Can an entire Linux userland of executables be packed into a single SQLite database, and how does the size compare to the original ELF files?

Yes, 723 executables pulling in 400 distinct shared libraries were packed into one SQLite database totaling 611.9 MiB, compared to 644.4 MiB for the original ELF files, roughly 6% overhead above raw program bytes. Deduplication of shared libraries and symbols across the whole closure falls out naturally from the database schema, unlike an AppImage-style model where the same programs would total 5.53 GiB.

_Developers exploring closure-based packaging and dedup strategies can follow this kind of systems research on daily.dev._

### How does a SQLite-based executable format get invoked as a runnable program on Linux?

SQLite reserves a 4-byte application_id field at byte offset 68 of its header, which gets stamped with the value SELF so an ordinary SQLite database never accidentally matches. Linux's binfmt_misc subsystem is then registered to recognize the SQLite magic bytes plus this SELF marker at offset 68, routing execution to a custom interpreter (self-exec) that reads program headers and symbol tables from the database instead of parsing ELF.

_Engineers curious about custom binary formats and binfmt_misc tricks can keep up with projects like this on daily.dev._

## Community discussion

Top comments from developers on daily.dev.

**@pdfopsdev** · 2 upvotes

> neat idea but that 5ms sqlite startup cost is going to hurt anything spawning short lived processes, think serverless cold starts or shell pipelines. dedup across a whole userland in one db is a genuinely good argument for it though.

**@agustinbarrientos** · 0 upvotes

> I think appliance images and developer environments are the sweet spot until SELF can share text pages across processes.

## Similar posts on daily.dev

- [Actually Queryable Executables](https://daily.dev/posts/actually-queryable-executables-2ahiklixd) · Farid Zakaria’s Blog · 0 upvotes · 0 comments
- [How programs get run: ELF binaries](https://daily.dev/posts/how-programs-get-run-elf-binaries-6ybn3cbnw) · Hacker News · 1 upvotes · 0 comments

---

Tags: [#linux](https://daily.dev/tags/linux), [#sqlite](https://daily.dev/tags/sqlite)

[View this post on daily.dev](https://daily.dev/posts/your-executable-is-a-sqlite-database-xpecfwhbu)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Your executable is a SQLite database","url":"https://daily.dev/posts/your-executable-is-a-sqlite-database-xpecfwhbu","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/your-executable-is-a-sqlite-database-xpecfwhbu"},"datePublished":"2026-08-24T04:53:02.481Z","dateModified":"2026-09-13T18:45:07.252Z","description":"A prototype called SELF (Structured Executable & Linkable Format) replaces the ELF binary format with an actual SQLite database file: the executable itself is...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/97bbbcff6af330db52ab2275fde5aa54?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/97bbbcff6af330db52ab2275fde5aa54?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Farid Zakaria’s Blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Farid Zakaria’s Blog","logo":"https://media.daily.dev/image/upload/s--YqqvRt90--/f_auto/v1723789280/logos/fzakaria","url":"https://daily.dev/sources/fzakaria"},"commentCount":2,"discussionUrl":"https://daily.dev/posts/your-executable-is-a-sqlite-database-xpecfwhbu","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":28},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":2}],"keywords":"linux,sqlite","timeRequired":"PT14M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Farid Zakaria’s Blog","item":"https://daily.dev/sources/fzakaria"},{"@type":"ListItem","position":3,"name":"Your executable is a SQLite database"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/your-executable-is-a-sqlite-database-xpecfwhbu","comment":[{"@type":"Comment","text":"neat idea but that 5ms sqlite startup cost is going to hurt anything spawning short lived processes, think serverless cold starts or shell pipelines. dedup across a whole userland in one db is a genuinely good argument for it though.","datePublished":"2026-08-24T18:07:26.231Z","url":"https://daily.dev/posts/xPeCfWhbU#c-EBJwnbQru","author":{"@type":"Person","name":"PDFops","url":"https://daily.dev/pdfopsdev","image":"https://media.daily.dev/image/upload/s---8isRBKc--/f_auto/v1782922291/avatars/avatar_orjMeK8QKaaVZwGq7ScPz?_a=BAMAMicg0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":2}},{"@type":"Comment","text":"I think appliance images and developer environments are the sweet spot until SELF can share text pages across processes.","datePublished":"2026-09-01T01:23:35.135Z","url":"https://daily.dev/posts/xPeCfWhbU#c-yy3qwhS7e","author":{"@type":"Person","name":"Agustin Barrientos","url":"https://daily.dev/agustinbarrientos","image":"https://media.daily.dev/image/upload/s--5ayxQnqn--/f_auto/v1788281802/avatars/avatar_wQYYVe5Tbj0NJ7C7qPoa8?_a=BAMAMicg0"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/your-executable-is-a-sqlite-database-xpecfwhbu#faq","mainEntity":[{"@type":"Question","name":"How much bigger is a SQLite-based executable format compared to a stripped ELF binary?","acceptedAnswer":{"@type":"Answer","text":"A stripped SELF (SQLite-based executable) file for coreutils is 1,794,048 bytes versus 1,768,632 bytes for the equivalent ELF binary, a difference within 1%. The overhead mostly comes from SQLite's b-tree structures and optional metadata tables used for debugging and tooling, which can be deleted in a transaction similar to running strip on an ELF file. Anyone weighing binary format trade-offs for size can track experiments like SQLite-as-executable through daily.dev."}},{"@type":"Question","name":"Can an entire Linux userland of executables be packed into a single SQLite database, and how does the size compare to the original ELF files?","acceptedAnswer":{"@type":"Answer","text":"Yes, 723 executables pulling in 400 distinct shared libraries were packed into one SQLite database totaling 611.9 MiB, compared to 644.4 MiB for the original ELF files, roughly 6% overhead above raw program bytes. Deduplication of shared libraries and symbols across the whole closure falls out naturally from the database schema, unlike an AppImage-style model where the same programs would total 5.53 GiB. Developers exploring closure-based packaging and dedup strategies can follow this kind of systems research on daily.dev."}},{"@type":"Question","name":"How does a SQLite-based executable format get invoked as a runnable program on Linux?","acceptedAnswer":{"@type":"Answer","text":"SQLite reserves a 4-byte application_id field at byte offset 68 of its header, which gets stamped with the value SELF so an ordinary SQLite database never accidentally matches. Linux's binfmt_misc subsystem is then registered to recognize the SQLite magic bytes plus this SELF marker at offset 68, routing execution to a custom interpreter (self-exec) that reads program headers and symbol tables from the database instead of parsing ELF. Engineers curious about custom binary formats and binfmt_misc tricks can keep up with projects like this on daily.dev."}}]}
```

