microsoft/FASTER · error · FasterException

Insufficient page size to write delta

Error message

Insufficient page size to write delta

What it means

During delta-log based recovery/write of page deltas, FASTER copies records into a delta log entry sized from the page size. After an Allocate still can't fit the record (destOffset + size > entryLength even after sealing and re-allocating), it throws "Insufficient page size to write delta" — the configured page size is too small for the delta entries being produced.

Solutions

  1. Increase the hybrid log PageSize (must remain a power of 2 and >= max record size with delta overhead).
  2. Reduce record/value sizes so deltas fit comfortably within the page size.
  3. Adjust the workload to use Read/Write instead of large Read-Modify-Write deltas where possible.

Example fix

// before
new LogSettings { PageSizeBits = 10 } // 1KB pages, too small for big deltas
// after
new LogSettings { PageSizeBits = 14 } // 16KB pages accommodate deltas
Defensive patterns

Strategy: validation

Validate before calling

// ensure page size comfortably exceeds max record size
class MaxRecord { public byte[] Data; }
if (maxRecordSizeBytes * 2 > (1 << logSettings.PageSizeBits))
    throw new ArgumentException("Increase PageSizeBits: max record + delta overhead exceeds page size");

Try / catch

try { session.RMW(key, input, output); } catch (FasterException) { /* raise PageSizeBits and reopen store */ }

Prevention

When it happens

Trigger: Performing operations whose deltas (logicalAddress + alignedRecordSize + record bytes) exceed the available delta entry capacity derived from the log's page size — i.e. very large values/records relative to PageSize, or Update operations producing oversized deltas.

Common situations: Configuring a small hybrid log page size (e.g. 1KB) while storing values of comparable size; workloads with large RMW payloads where delta logs fill a whole page; tuning PageSize down to save memory without checking max record size.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15). Data as JSON: /api/errors/55be89b36618d46c. Report an issue: GitHub.

Appendix: source

Thrown at cs/src/core/Allocator/AllocatorBase.cs:521

                        {
                            ref var info = ref GetInfo(physicalAddress);
                            var (recordSize, alignedRecordSize) = GetRecordSize(physicalAddress);
                            if (info.Dirty)
                            {
                                info.ClearDirtyAtomic(); // there may be read locks being taken, hence atomic
                                int size = sizeof(long) + sizeof(int) + alignedRecordSize;
                                if (destOffset + size > entryLength)
                                {
                                    deltaLog.Seal(destOffset);
                                    deltaLog.Allocate(out entryLength, out destPhysicalAddress);
                                    destOffset = 0;
                                    if (destOffset + size > entryLength)
                                    {
                                        deltaLog.Seal(0);
                                        deltaLog.Allocate(out entryLength, out destPhysicalAddress);
                                    }
                                    if (destOffset + size > entryLength)
                                        throw new FasterException("Insufficient page size to write delta");
                                }
                                *(long*)(destPhysicalAddress + destOffset) = logicalAddress;
                                destOffset += sizeof(long);
                                *(int*)(destPhysicalAddress + destOffset) = alignedRecordSize;
                                destOffset += sizeof(int);
                                Buffer.MemoryCopy((void*)physicalAddress, (void*)(destPhysicalAddress + destOffset), alignedRecordSize, alignedRecordSize);
                                destOffset += alignedRecordSize;
                            }
                            physicalAddress += alignedRecordSize;
                            logicalAddress += alignedRecordSize;
                        }
                        epoch.ProtectAndDrain();
                    }
                }
                finally
                {
                    if (epochTaken)
                        epoch.Suspend();

View on GitHub (pinned to 321d872eab)