@@ -498,11 +498,19 @@ export class Indexer {
498498 }
499499 }
500500
501- const queue = new PQueue ( { concurrency : 3 } ) ;
501+ // GitHub Models API rate limit: 15 requests/minute for embeddings
502+ // Use concurrency 1 with 4-second delay to stay under limit (15 req/min = 1 req per 4 sec)
503+ const queue = new PQueue ( { concurrency : 1 , interval : 4000 , intervalCap : 1 } ) ;
502504 const dynamicBatches = createDynamicBatches ( chunksNeedingEmbedding ) ;
505+ let rateLimitBackoffMs = 0 ;
503506
504507 for ( const batch of dynamicBatches ) {
505508 queue . add ( async ( ) => {
509+ // Additional backoff if we've been rate limited
510+ if ( rateLimitBackoffMs > 0 ) {
511+ await new Promise ( resolve => setTimeout ( resolve , rateLimitBackoffMs ) ) ;
512+ }
513+
506514 try {
507515 const result = await pRetry (
508516 async ( ) => {
@@ -511,15 +519,16 @@ export class Indexer {
511519 } ,
512520 {
513521 retries : this . config . indexing . retries ,
514- minTimeout : this . config . indexing . retryDelayMs ,
515- maxTimeout : 30000 ,
522+ minTimeout : Math . max ( this . config . indexing . retryDelayMs , 5000 ) , // Minimum 5s between retries
523+ maxTimeout : 60000 , // Max 60s backoff
516524 factor : 2 ,
517525 onFailedAttempt : ( error ) => {
518526 const message = getErrorMessage ( error ) ;
519527 if ( isRateLimitError ( error ) ) {
520- queue . concurrency = 1 ;
528+ // Exponential backoff: 10s, 20s, 40s...
529+ rateLimitBackoffMs = Math . min ( 60000 , ( rateLimitBackoffMs || 5000 ) * 2 ) ;
521530 console . error (
522- `Rate limited (attempt ${ error . attemptNumber } /${ error . retriesLeft + error . attemptNumber } ): waiting before retry...`
531+ `Rate limited (attempt ${ error . attemptNumber } /${ error . retriesLeft + error . attemptNumber } ): waiting ${ rateLimitBackoffMs / 1000 } s before retry...`
523532 ) ;
524533 } else {
525534 console . error (
@@ -529,6 +538,11 @@ export class Indexer {
529538 } ,
530539 }
531540 ) ;
541+
542+ // Success - gradually reduce backoff
543+ if ( rateLimitBackoffMs > 0 ) {
544+ rateLimitBackoffMs = Math . max ( 0 , rateLimitBackoffMs - 2000 ) ;
545+ }
532546
533547 const items = batch . map ( ( chunk , idx ) => ( {
534548 id : chunk . id ,
0 commit comments