microsoft/garnet · error · TsavoriteException
{nameof(logSettings.MemorySize)} must be at least {LogSettin
Error message
{nameof(logSettings.MemorySize)} must be at least {LogSettings.kMinPageCount}x the page size ({1L << logSettings.PageSizeBits}) What it means
Constructor validation: when MemorySize is non-zero it must be at least kMinPageCount (2) times the page size (1 << PageSizeBits). The circular buffer must hold at least two pages so that flush/eviction can proceed while one page is being written. Default MemorySize (16GiB) and PageSizeBits (25 => 32MiB) give 512 pages, comfortably above the floor.
Source
Thrown at libs/storage/Tsavorite/cs/src/core/Allocator/AllocatorBase.cs:560
asyncGetFromDiskCallbackDelegate = AsyncGetFromDiskCallback;
this.transientObjectIdMap = transientObjectIdMap;
// Validation
if (logSettings.PageCount == 0 && logSettings.MemorySize == 0)
throw new TsavoriteException($"{nameof(logSettings.PageCount)} or {nameof(logSettings.MemorySize)} must be specified");
if (logSettings.PageSizeBits < LogSettings.kMinPageSizeBits || logSettings.PageSizeBits > LogSettings.kMaxPageSizeBits)
throw new TsavoriteException($"{nameof(logSettings.PageSizeBits)} must be between {LogSettings.kMinPageSizeBits} and {LogSettings.kMaxPageSizeBits}");
if (logSettings.PageSizeBits < PageHeader.SizeBits)
throw new TsavoriteException($"{nameof(logSettings.PageSizeBits)} must be >= PageHeader.SizeBits {PageHeader.SizeBits}");
if (logSettings.PageCount > MemoryUtils.ArrayMaxLength)
throw new TsavoriteException($"{nameof(logSettings.PageCount)} must be less than or equal to the maximum array length ({MemoryUtils.ArrayMaxLength})");
if (logSettings.SegmentSizeBits < LogSettings.kMinMainLogSegmentSizeBits || logSettings.SegmentSizeBits > LogSettings.kMaxSegmentSizeBits)
throw new TsavoriteException($"{nameof(logSettings.SegmentSizeBits)} must be between {LogSettings.kMinMainLogSegmentSizeBits} and {LogSettings.kMaxSegmentSizeBits}");
if (logSettings.MemorySize != 0 && (logSettings.MemorySize < 1L << LogSettings.kMinMemorySizeBits || logSettings.MemorySize > 1L << LogSettings.kMaxMemorySizeBits))
throw new TsavoriteException($"{nameof(logSettings.MemorySize)} must be between {1L << LogSettings.kMinMemorySizeBits} and {1L << LogSettings.kMaxMemorySizeBits}, or may be 0 for ReadOnly TsavoriteLog");
if ((logSettings.MemorySize != 0) && (logSettings.MemorySize < (1L << logSettings.PageSizeBits) * LogSettings.kMinPageCount))
throw new TsavoriteException($"{nameof(logSettings.MemorySize)} must be at least {LogSettings.kMinPageCount}x the page size ({1L << logSettings.PageSizeBits})");
if (logSettings.MutableFraction < 0.0 || logSettings.MutableFraction > 1.0)
throw new TsavoriteException($"{nameof(logSettings.MutableFraction)} must be >= 0.0 and <= 1.0");
if (logSettings.ReadCacheSettings is not null)
{
var rcs = logSettings.ReadCacheSettings;
if (rcs.PageCount == 0 && rcs.MemorySize == 0)
throw new TsavoriteException($"{nameof(rcs.PageCount)} or {nameof(rcs.MemorySize)} must be specified");
if (rcs.PageSizeBits < LogSettings.kMinPageSizeBits || rcs.PageSizeBits > LogSettings.kMaxPageSizeBits)
throw new TsavoriteException($"{nameof(rcs.PageSizeBits)} must be between {LogSettings.kMinPageSizeBits} and {LogSettings.kMaxPageSizeBits}");
if (rcs.PageCount > MemoryUtils.ArrayMaxLength)
throw new TsavoriteException($"{nameof(rcs.PageCount)} must be less than or equal to the maximum array length ({MemoryUtils.ArrayMaxLength})");
if (rcs.MemorySize != 0 && (rcs.MemorySize < 1L << LogSettings.kMinMemorySizeBits || rcs.MemorySize > 1L << LogSettings.kMaxMemorySizeBits))
throw new TsavoriteException($"{nameof(rcs.MemorySize)} must be between {1L << LogSettings.kMinMemorySizeBits} and {1L << LogSettings.kMaxMemorySizeBits}");
if ((rcs.MemorySize != 0) && (rcs.MemorySize < (1L << rcs.PageSizeBits) * 2))
throw new TsavoriteException($"{nameof(logSettings.MemorySize)} must be at least twice the page size ({1L << rcs.PageSizeBits})");
if (rcs.SecondChanceFraction < 0.0 || rcs.SecondChanceFraction > 1.0)
throw new TsavoriteException($"{rcs.SecondChanceFraction} must be >= 0.0 and <= 1.0");
}View on GitHub (pinned to 951b0fc683)
Solutions
- Raise MemorySize to at least 2 * (1 << PageSizeBits).
- Or lower PageSizeBits so that MemorySize >= 2 pages.
- Keep the default MemorySize unless you also adjust PageSizeBits consistently.
Example fix
// before logSettings.PageSizeBits = 25; // 32MiB page logSettings.MemorySize = 1L << 24; // 16MiB -> < 2 pages // after logSettings.MemorySize = 1L << 26; // 64MiB -> 2 pages, the minimum
Defensive patterns
Strategy: validation
Validate before calling
// MemorySize must cover >= 2 pages (kMinPageCount).
const int kMinPageCount = 2;
long minMem = (1L << logSettings.PageSizeBits) * kMinPageCount;
if (logSettings.MemorySize != 0 && logSettings.MemorySize < minMem)
logSettings.MemorySize = minMem; // or raise PageSizeBits-adjusted floor Try / catch
try { new TsavoriteKV<K,V>(logSettings, ...); }
catch (TsavoriteException ex) when (ex.Message.Contains("MemorySize") && ex.Message.Contains("at least") && ex.Message.Contains("the page size"))
{ /* raise MemorySize to >= 2 * (1<<PageSizeBits) and recreate */ } Prevention
- When raising PageSizeBits, recompute the MemorySize floor as 2 * (1 << PageSizeBits).
- Keep the default MemorySize unless you also retune PageSizeBits.
- Add a unit test that asserts MemorySize >= 2 pages for your configs.
When it happens
Trigger: Choosing a small MemorySize relative to a large PageSizeBits, e.g. PageSizeBits=25 (32MiB pages) with MemorySize=16MiB: 16MiB < 2 * 32MiB, so this fires.
Common situations: Tuning for large pages without raising MemorySize; benchmark configs that shrank MemorySize but kept big pages.
Related errors
- {nameof(logSettings.MemorySize)} must be at least twice the
- {nameof(logSettings.PageCount)} or {nameof(logSettings.Memor
- {nameof(logSettings.PageSizeBits)} must be between {LogSetti
- {nameof(logSettings.PageSizeBits)} must be >= PageHeader.Siz
- {nameof(logSettings.MemorySize)} must be between {1L << LogS
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/7101b5a586e3b1f2.
Report an issue: GitHub.