TIL: SQLite does not check foreign keys by default
by Paweł Świątkowski
08 Jul 2026
I have to admit: I generally missed all the hype around putting SQLite everywhere, especially in production, that has been going on for a while. To me SQLite is generally a dev (or local) database, one that is simple to setup. But if I need something “searious”, I always reach for battle-tested PostgreSQL.
For that reason, I never paid too much attention to configuring SQLite, mostly using it just as is. So I was quite disappointed seeing this:
sqlite> create table users (id integer primary key, name text);
sqlite> create table posts (id integer primary key, title text, user_id integer, foreign key(user_id) references users(id));
sqlite> insert into users (id, name) values (1, 'john');
sqlite> insert into posts (id, title, user_id) values (1, 'my first post', 2);
sqlite> select * from posts;
╭────┬───────────────┬─────────╮
│ id │ title │ user_id │
╞════╪═══════════════╪═════════╡
│ 1 │ my first post │ 2 │
╰────┴───────────────┴─────────╯
Ugh, what? That is not right. There is a foreign key, but I just happily inserted a row violating it!
It turns out you need to opt in for foreign key checks:
sqlite> pragma foreign_keys = on;
sqlite> insert into posts (id, title, user_id) values (2, 'my second post', 2);
Error near line 9: FOREIGN KEY constraint failed
Ok, now we’re talking!
Sounds like pretty important thing to remember when you are working with your SQLite.