{"record":{"id":"27bbd97c100e3a16","repo":"microsoft/garnet","slug":"aofmemorysize-effective-effectivememory-after-r","errorCode":null,"errorMessage":"AofMemorySize (effective {effectiveMemory} after rounding down to a power of two) must be at least twice AofPageSize (effective {effectivePage}). Increase --aof-memory to at least {minMemory}, or reduce --aof-page-size.","messagePattern":"AofMemorySize \\(effective (.+?) after rounding down to a power of two\\) must be at least twice AofPageSize \\(effective (.+?)\\)\\. Increase --aof-memory to at least (.+?), or reduce --aof-page-size\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"libs/server/Servers/GarnetServerOptions.cs","lineNumber":987,"sourceCode":"            var memorySizeBits = AofMemorySizeBits();\n            var pageSizeBits = AofPageSizeBits();\n            var segmentSizeBits = AofSegmentSizeBits();\n\n            // Tsavorite requires MemorySize >= 2 * PageSize (so at least two pages fit in memory).\n            // With power-of-two rounded sizes this means memorySizeBits >= pageSizeBits + 1.\n            // Catch this here so we can produce a Garnet-specific error that names the actual\n            // AofMemorySize / AofPageSize config options, rather than the generic Tsavorite\n            // \"MemorySize must be at least twice the page size\" message which does not say AOF.\n            if (memorySizeBits <= pageSizeBits)\n            {\n                var effectiveMemory = PrettySize(1L << memorySizeBits);\n                var effectivePage = PrettySize(1L << pageSizeBits);\n                var minMemory = PrettySize(1L << (pageSizeBits + 1));\n                var msg = $\"AofMemorySize (effective {effectiveMemory} after rounding down to a power of two) \" +\n                          $\"must be at least twice AofPageSize (effective {effectivePage}). \" +\n                          $\"Increase --aof-memory to at least {minMemory}, or reduce --aof-page-size.\";\n                logger?.LogError(\"{msg}\", msg);\n                throw new Exception(msg);\n            }\n\n            if (pageSizeBits > segmentSizeBits)\n            {\n                var effectivePage = PrettySize(1L << pageSizeBits);\n                var effectiveSegment = PrettySize(1L << segmentSizeBits);\n                var msg = $\"AofPageSize (effective {effectivePage} after rounding down to a power of two) \" +\n                          $\"cannot be larger than AofSegmentSize (effective {effectiveSegment}). \" +\n                          $\"Increase --aof-segment-size to at least {effectivePage}, or reduce --aof-page-size.\";\n                logger?.LogError(\"{msg}\", msg);\n                throw new Exception(msg);\n            }\n\n            // AofPageSize must be at least twice the main-log PageSize. An AOF entry mirrors a single\n            // main-log write (key + value/input + small overhead); raw-string SETs can be as large as\n            // the main-log PageSize (values above MaxInlineValueSize overflow to the heap on the main\n            // store but are still written in full to the AOF), and object commands like LPUSH/HSET can\n            // push the AOF entry even higher. Throw a clear error here so users do not hit the runtime","sourceCodeStart":969,"sourceCodeEnd":1005,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/server/Servers/GarnetServerOptions.cs#L969-L1005","documentation":"Garnet validates that the AOF (Append-Only File) in-memory buffer is at least twice the AOF page size, because Tsavorite's hybrid log requires a minimum of two pages resident in memory. The check uses log2 bit values: memorySizeBits <= pageSizeBits means the effective memory is less than 2× the page. If violated, the server aborts startup before allocating any device or commit manager.","triggerScenarios":"Calling GetAofSettings() when AofMemorySizeBits() <= AofPageSizeBits(). Occurs when --aof-memory (after power-of-two rounding) is less than 2× --aof-page-size. For example, --aof-memory 32m --aof-page-size 32m produces memorySizeBits == pageSizeBits.","commonSituations":"Copying a config template that sets --aof-page-size high without proportionally raising --aof-memory; upgrading Garnet versions where AOF defaults changed; tuning AOF page size for write throughput and forgetting the memory must be at least double.","solutions":["Increase --aof-memory to at least twice the effective --aof-page-size (e.g. if page is 32m, set memory to 64m).","Reduce --aof-page-size so that the existing --aof-memory is at least double it.","Remove explicit --aof-page-size and --aof-memory overrides entirely to use Garnet's safe defaults."],"exampleFix":"// before\n--aof-memory 32m --aof-page-size 32m\n\n// after\n--aof-memory 64m --aof-page-size 32m","handlingStrategy":"validation","validationCode":"// Validate before starting the server\nvar memBits = options.AofMemorySizeBits();\nvar pageBits = options.AofPageSizeBits();\nif (memBits <= pageBits)\n    throw new InvalidOperationException($\"AOF memory ({1L << memBits} bytes) must be at least twice AOF page size ({1L << pageBits} bytes).\");","typeGuard":null,"tryCatchPattern":"// Wrap GetAofSettings in startup validation\ntry { options.GetAofSettings(dbId, out var settings); }\ncatch (Exception ex) when (ex.Message.Contains(\"AofMemorySize\"))\n{ logger.LogError(\"AOF config invalid: {Msg}. Fix --aof-memory or --aof-page-size.\", ex.Message); throw; }","preventionTips":["Always set --aof-memory to at least 2× --aof-page-size.","When changing --aof-page-size, audit --aof-memory in the same change.","Use a config validation script that checks all size relationships before deployment."],"tags":["aof","configuration","startup","garnet"],"backgroundTag":null,"analyzedSha":"951b0fc6838721f89d102c2bbe1b914e8d39d700","analyzedAt":"2026-08-13T19:01:32.939Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}