{"record":{"id":"6d2c5376a563dbae","repo":"gofr-dev/gofr","slug":"burst-must-be-greater-than-requests-per-window","errorCode":null,"errorMessage":"burst must be greater than requests per window","messagePattern":"burst must be greater than requests per window","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/service/rate_limiter_config.go","lineNumber":12,"sourceCode":"package service\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n)\n\nvar (\n\terrInvalidRequestRate     = errors.New(\"requests must be greater than 0 per configured time window\")\n\terrBurstLessThanRequests  = errors.New(\"burst must be greater than requests per window\")\n\terrInvalidRedisResultType = errors.New(\"unexpected Redis result type\")\n)\n\nconst (\n\tunknownServiceKey = \"unknown\"\n\tmethodHTTP        = \"http\"\n\tmethodHTTPS       = \"https\"\n)\n\n// RateLimiterConfig with custom keying support.\ntype RateLimiterConfig struct {\n\tRequests float64                    // Number of requests allowed\n\tWindow   time.Duration              // Time window (e.g., time.Minute, time.Hour)\n\tBurst    int                        // Maximum burst capacity (must be > 0)\n\tKeyFunc  func(*http.Request) string // Optional custom key extraction\n\tStore    RateLimiterStore\n}\n","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/service/rate_limiter_config.go#L1-L30","documentation":"errBurstLessThanRequests (rate_limiter_config.go:12) is returned by RateLimiterConfig.Validate when Burst < Requests per window — the burst capacity must be at least the steady-state request rate or the limiter would throttle below its own configured rate. Validate still self-heals by setting Burst = int(Requests).","triggerScenarios":"Validate finds float64(config.Burst) < config.Requests — e.g. Requests: 100, Burst: 10 — typically after Burst was left at 0 (then defaulted to 10) or set deliberately lower than Requests.","commonSituations":"Raising Requests in config without revisiting Burst; assuming Burst is optional and leaving it unset while Requests > 10; copying an example tuned for a low request rate.","solutions":["Set Burst >= Requests, e.g. Requests: 100, Burst: 100 (or higher for headroom).","Handle Validate's returned error; note Validate already corrected Burst, so the error is also a signal your config didn't express intent.","Derive Burst from Requests programmatically instead of hardcoding independent values."],"exampleFix":"// before\ncfg := &service.RateLimiterConfig{Requests: 100, Window: time.Minute, Burst: 10}\n// after\ncfg := &service.RateLimiterConfig{Requests: 100, Window: time.Minute, Burst: 120}","handlingStrategy":"validation","validationCode":"if float64(cfg.Burst) < cfg.Requests {\n\treturn fmt.Errorf(\"burst (%d) must be >= requests (%f)\", cfg.Burst, cfg.Requests)\n}","typeGuard":"func validBurst(cfg *service.RateLimiterConfig) bool {\n\treturn cfg != nil && float64(cfg.Burst) >= cfg.Requests\n}","tryCatchPattern":"if err := cfg.Validate(); err != nil {\n\tif errors.Is(err, errBurstLessThanRequests) {\n\t\tlog.Printf(\"burst corrected to requests rate by Validate: %v\", err)\n\t}\n}","preventionTips":["Derive Burst from Requests (Burst >= Requests) instead of hardcoding it independently.","Re-check Burst whenever you raise Requests in configuration.","Don't leave Burst unset while Requests > the 10 default burst.","Assert burst >= requests in unit tests for limiter construction."],"tags":["rate-limiting","config","validation"],"backgroundTag":"invalid-rate-limit-config","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}