{"record":{"id":"ac88c40a496afd44","repo":"vitessio/vitess","slug":"in-memory-row-count-exceeded-allowed-limit-of-d","errorCode":null,"errorMessage":"in-memory row count exceeded allowed limit of %d","messagePattern":"in-memory row count exceeded allowed limit of (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/engine/join.go","lineNumber":94,"sourceCode":"\t\tfor k, col := range jn.Vars {\n\t\t\tjoinVars[k] = sqltypes.ValueBindVariable(lrow[col])\n\t\t}\n\t\trresult, err := vcursor.ExecutePrimitive(ctx, jn.Right, combineVars(bindVars, joinVars), wantfields)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif wantfields {\n\t\t\twantfields = false\n\t\t\tresult.Fields = joinFields(lresult.Fields, rresult.Fields, jn.Cols)\n\t\t}\n\t\tfor _, rrow := range rresult.Rows {\n\t\t\tresult.Rows = append(result.Rows, joinRows(lrow, rrow, jn.Cols))\n\t\t}\n\t\tif jn.Opcode == LeftJoin && len(rresult.Rows) == 0 {\n\t\t\tresult.Rows = append(result.Rows, joinRows(lrow, nil, jn.Cols))\n\t\t}\n\t\tif vcursor.ExceedsMaxMemoryRows(len(result.Rows)) {\n\t\t\treturn nil, fmt.Errorf(\"in-memory row count exceeded allowed limit of %d\", vcursor.MaxMemoryRows())\n\t\t}\n\t}\n\treturn result, nil\n}\n\nfunc bindvarForType(field *querypb.Field) *querypb.BindVariable {\n\tbv := &querypb.BindVariable{\n\t\tType:  field.Type,\n\t\tValue: nil,\n\t}\n\tswitch field.Type {\n\tcase querypb.Type_INT8, querypb.Type_UINT8, querypb.Type_INT16, querypb.Type_UINT16,\n\t\tquerypb.Type_INT32, querypb.Type_UINT32, querypb.Type_INT64, querypb.Type_UINT64:\n\t\tbv.Value = []byte(\"0\")\n\tcase querypb.Type_FLOAT32, querypb.Type_FLOAT64:\n\t\tbv.Value = []byte(\"0e0\")\n\tcase querypb.Type_DECIMAL:\n\t\tsize := max(1, int(field.ColumnLength-field.Decimals))","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/engine/join.go#L76-L112","documentation":"Join and other in-memory engine primitives materialize rows in vtgate memory. Before returning, TryExecute checks vcursor.ExceedsMaxMemoryRows; when the joined result set exceeds --max_memory_rows, execution aborts with this error instead of risking OOM on the gate.","triggerScenarios":"Executing a JOIN query whose materialized result (left rows joined with right rows) exceeds the vtgate --max_memory_rows limit; called from TryExecute when appending joinRows results.","commonSituations":"Cartesian joins or large fan-out joins without LIMIT; --max_memory_rows left at its low default (100k); analytics-style queries run through vtgate that should go to a different path.","solutions":["Add filtering/LIMIT to reduce the join result size","Increase --max-memory-rows on vtgate if the query is legitimate and the host has memory headroom","Rewrite the query to avoid large cross joins, or run it via a streaming-capable path / external query engine"],"exampleFix":"// before\nSELECT * FROM a JOIN b ON a.k = b.k\n// after\nSELECT * FROM a JOIN b ON a.k = b.k WHERE a.tenant = :tenant LIMIT 1000","handlingStrategy":"fallback","validationCode":"// estimate rows first\nn, err := countJoinRows(query)\nif err == nil && uint64(n) > maxMemoryRows {\n    return errors.New(\"join would exceed in-memory row limit; add LIMIT or filters\")\n}","typeGuard":null,"tryCatchPattern":"res, err := execute(query)\nif err != nil && strings.Contains(err.Error(), \"in-memory row count exceeded allowed limit\") {\n    // rewrite query with LIMIT/pagination or route to a batch engine\n}","preventionTips":["Set --max-memory-rows appropriately for vtgate host memory and expected workloads","Add LIMIT/ key-range filters to join queries issued through vtgate","Avoid unbounded cross joins in OLTP paths; paginate large result sets","Alert on this error rate to catch runaway queries early"],"tags":["vtgate","join","memory-limit","query-planning"],"backgroundTag":"max-memory-rows-exceeded","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}