All original content is created in Ukrainian. Not all content has been translated yet. Some posts may only be available in Ukrainian.Learn more

Why does PostgreSQL skip IDs when saving new records? (Heroku)

Post cover: Why does PostgreSQL skip IDs when saving new records? (Heroku)
This content has been automatically translated from Ukrainian.
Checking the last ID in the database, and it is unexpectedly larger than the actual number of records. Why does this happen?
In Heroku (and generally in PostgreSQL), ID values can be non-sequential for several reasons:

Auto-increment field (serial / bigserial) and transactions

  • In Rails, IDs are usually serial or bigserial, which use SEQUENCE to generate unique values.
  • If a transaction that allocated an ID is rolled back (ROLLBACK), that value is no longer used, but the SEQUENCE increments further. For example, if an object is created with id = 4, and then the transaction is rolled back, the next record will receive id = 5, and 4 will remain skipped.

Concurrent queries

  • In cloud environments like Heroku, there can be many concurrent processes writing to the database at the same time.
  • If two queries create new records simultaneously, they may receive IDs in different orders.

Dyno restart (Heroku) and SEQUENCE caching

  • PostgreSQL caches SEQUENCE values, which helps improve performance.
  • If a Dyno (Heroku server) restarts, cached values may be lost, and PostgreSQL will skip several IDs.

Deleted records

  • If you delete records from a table (DELETE), their IDs are not reused.
  • For example, if there were records with IDs = 1, 2, 3, and then you deleted 2, the next ID will still be 4.

How to check SEQUENCE?

Execute in the PostgreSQL console:
SELECT last_value, is_called FROM your_table_id_seq;
Or manually reset the value:
SELECT setval('your_table_id_seq', (SELECT MAX(id) FROM your_table));
This will align the SEQUENCE but will not fill in the gaps in already created IDs. This is normal behavior for PostgreSQL. If you critically need sequential IDs, you can use ROW_NUMBER(), but it is not recommended for primary IDs.

This post doesn't have any additions from the author yet.

Що таке Memoization (приклади Ruby та Ruby on Rails)?
20 Feb 18:16

Що таке Memoization (приклади Ruby та Ruby on Rails)?

meme code
meme code@memecode
Що таке debounce у JavaScript і чому це важливо?
21 Mar 16:39

Що таке debounce у JavaScript і чому це важливо?

meme code
meme code@memecode
What is CFB (Cipher Feedback)?
21 Mar 16:53

What is CFB (Cipher Feedback)?

meme code
meme code@memecode
Що таке XOR і як він працює?
21 Mar 17:05

Що таке XOR і як він працює?

meme code
meme code@memecode
Embed програмування: що це таке і з чого почати
24 Mar 16:48

Embed програмування: що це таке і з чого почати

meme code
meme code@memecode
Pessimistic Lock у Rails: що це таке і коли застосовувати. Які є альтернативи?
31 Mar 17:45

Pessimistic Lock у Rails: що це таке і коли застосовувати. Які є альтернативи?

meme code
meme code@memecode
[Codecov] What is the difference between patch and project coverage?
09 Apr 16:03

[Codecov] What is the difference between patch and project coverage?

meme code
meme code@memecode
How do Scratch courses help children develop soft skills?
11 Apr 18:24

How do Scratch courses help children develop soft skills?

meme code
meme code@memecode
24 Apr 20:17

Фіксимо minikube "You are trying to run the amd64 binary on an M1 system."

meme code
meme code@memecode
24 Apr 20:55

Фіксимо minikube на Mac з М1 (відмовляємось від qemu, запускаємо на docker)

meme code
meme code@memecode
Where to find an older version of Google Chrome and download it? Using an old Mac as an example.
25 Apr 23:02

Where to find an older version of Google Chrome and download it? Using an old Mac as an example.

meme code
meme code@memecode
09 May 19:27

[FIXED] cannot load such file -- html/pipeline (LoadError) виникає під час rails generate thredded:install

meme code
meme code@memecode