Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9089657
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T22:12:07+00:00 2026-06-16T22:12:07+00:00

Yes, fillfactor again. I spend many hours reading and I can’t decide what’s best

  • 0

Yes, fillfactor again. I spend many hours reading and I can’t decide what’s best for each case. I don’t understand when and how fragmentation happens. I’m migrating a database from MS SQL Server to PostgreSQL 9.2.

Case 1

10-50 inserts / minute in a sequential (serial) PK, 20-50 reads / hour.

CREATE TABLE dev_transactions (
  transaction_id serial NOT NULL,
  transaction_type smallint NOT NULL,
  moment timestamp without time zone NOT NULL,
  gateway integer NOT NULL,
  device integer NOT NULL,
  controler smallint NOT NULL,
  token integer,
  et_mode character(1),
  status smallint NOT NULL,
  CONSTRAINT pk_dev_transactions PRIMARY KEY (transaction_id)
);

Case 2

Similar structure, index for serial PK, writes in blocks (one shot) of ~ 50.000 registers every 2 months, readings 10-50 / minute.

Does a 50% fillfactor mean that each insert generates a new page and moves 50% of existing rows to a newly generated page?

Does a 50% fillfactor mean frees space is allocated between physical rows in new data pages?

A new page is generated only if there is no free space left in existing pages?

As you can see I’m very confused; I would appreciate some help — maybe a good link to read about PostgreSQL and index fillfactor.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-16T22:12:07+00:00Added an answer on June 16, 2026 at 10:12 pm

    FILLFACTOR

    With only INSERT and SELECT you should use a FILLFACTOR of 100 for tables (which is the default anyway). There is no point in leaving wiggle room per data page if you are not going to "wiggle" with UPDATEs.

    The mechanism behind FILLFACTOR is simple. INSERTs only fill data pages (usually 8 kB blocks) up to the percentage declared by the FILLFACTOR setting. Also, whenever you run VACUUM FULL or CLUSTER on the table, the same wiggle room per block is re-established. Ideally, this allows UPDATE to store new row versions in the same data page, which can provide a substantial performance boost when dealing with lots of UPDATEs. Also beneficial in combination with H.O.T. updates. See:

    • Redundant data in update statements

    Indexes need more wiggle room by design. They have to store new entries at the right position in leaf pages. Once a page is full, a relatively costly "page split" is needed. So indexes tend to bloat more than tables. The default FILLFACTOR for a (default) B-Tree index is 90 (varies per index type). And wiggle room makes sense for just INSERTs, too. The best strategy heavily depends on write patterns.

    Example: If new inserts have steadily growing values (typical case for a serial or timestamp column), then there are basically no page-splits, and you might go with FILLFACTOR = 100 (or a bit lower to allows for some noise).
    For a random distribution of new values, you might go below the default 90 …

    Basic source of information: the manual for CREATE TABLE and CREATE INDEX.

    Other optimization

    But you can do something else – since you seem to be a sucker for optimization … 🙂

    CREATE TABLE dev_transactions(
      transaction_id   serial PRIMARY KEY
    , gateway          integer NOT NULL
    , moment           timestamp NOT NULL
    , device           integer NOT NULL
    , transaction_type smallint NOT NULL
    , status           smallint NOT NULL
    , controller       smallint NOT NULL
    , token            integer
    , et_mode          character(1)
    );
    

    This optimizes your table with regard to data alignment and avoids padding for a typical 64 bit server and saves a few bytes, probably just 8 byte on average – you typically can’t squeeze out much with "column tetris":

    • Calculating and saving space in PostgreSQL

    Keep NOT NULL columns at the start of the table for a very small performance bonus.

    Your table has 9 columns. The initial ("cost-free") 1-byte NULL bitmap covers 8 columns. The 9th column triggers an additional 8 bytes for the extended NULL bitmap – if there are any NULL values in the row.

    If you make et_mode and token NOT NULL, all columns are NOT NULL and there is no NULL bitmap, freeing up 8 bytes per row.
    This even works per row if some columns can be NULL. If all fields of the same row have values, there is no NULL bitmap for the row. In your special case, this leads to the paradox that filling in values for et_mode and token can make your storage size smaller or at least stay the same:

    • Do nullable columns occupy additional space in PostgreSQL?

    Basic source of information: the manual on Database Physical Storage.

    Compare the size of rows (filled with values) with your original table to get definitive proof:

    SELECT pg_column_size(t) FROM dev_transactions t;
    

    (Plus maybe padding between rows, as the next row starts at a multiple of 8 bytes.)

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Yes, it's the infamous viewstate again! Now I am aware that problems can ocurr
Yes, this question has been asked many times, and I've been looking and reading
Yes, I have searched and tried many techniques, but nothing seems to work. Here
Yes, I know this question has been asked before, but I can't find an
Yes, I am still on Drupal 5. Don't make fun. I created a category
Yes, this question has been asked before, but I don't feel there's been a
yes this question is asked some times. but I can't find an answer for
Yes, I understand that JavaScript doesn't have classes per se, so I'll just throw
Yes. my problem is very common in StackOverFlow, but I don't see the real
Yes i read the article on sequence points . However i could not understand

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.