I was talking to a friend who said he picked MongoDB because he had a bunch of schemaless JSON and just needed somewhere to throw it.

Fair enough. But Postgres can do that too.

Postgres has both json and jsonb columns. json stores the original JSON text exactly as provided. jsonb stores a parsed binary representation, which is usually faster to query and can be indexed. Unless preserving the original formatting matters, jsonb is probably what you want.

You can start with almost no structure:

create table events (
  id bigint generated always as identity primary key,
  payload jsonb not null
);

Then, when the data settles down and you want a little more structure, add it without moving to another database:

alter table events
add constraint payload_has_string_type
check (
  payload ? 'type'
  and jsonb_typeof(payload->'type') = 'string'
);

Now every payload still gets to be flexible, but it must have a string called type. You can add normal columns, more constraints, relationships, and indexes whenever you actually need them.

So you do not necessarily need to settle for a NoSQL database just because your data starts out schemaless. With Postgres, you can throw in JSON today and grow into a schema tomorrow without changing databases.

If you’re looking for a quick way to get Postgres up and running, check out Supabase.