If your Vim binary includes the patch [8.2.0877](https://github.com/vim/vim/releases/tag/v8.2.0877), you can get the search statistics via the `searchcount()` function.  And the latter is not limited to 99 matches.

You can invoke it right after a `/` search with a `CmdlineLeave` autocmd, and right after a `n` motion by installing a wrapper mapping around the latter.

[Example](https://github.com/lacygoill/vim-search/blob/6bd25440074834cfa4030d7bd924859cbe72eeca/autoload/search.vim#L88-L137):

    const s:MAXCOUNT = 1000
    const s:TIMEOUT = 500

    augroup index_after_slash | au!
        au CmdlineLeave /,\? call s:index_after_slash()
    augroup END

    fu s:index_after_slash() abort
        if getcmdline() is# '' || state() =~# 'm'
            return
        endif
        call timer_start(0, {-> mode() =~# '[nv]' ? s:search_index() : 0})
    endfu

    fu s:search_index() abort
        try
            let result = searchcount(#{maxcount: s:MAXCOUNT, timeout: s:TIMEOUT})
            let [current, total, incomplete] = [result.current, result.total, result.incomplete]
        catch
            echohl ErrorMsg | echom v:exception | echohl NONE
            return ''
        endtry
        let msg = ''
        let pat = substitute(@/, '\%x00', '^@', 'g')
        if incomplete == 0
            let msg = printf('[%*d/%d] %s', len(total), current, total, pat)
        elseif incomplete == 1 " recomputing took too much time
            let msg = printf('[?/??] '..%s', pat)
        elseif incomplete == 2 " too many matches
            if result.total == (result.maxcount+1) && result.current <= result.maxcount
                let msg = printf('[%*d/>%d] %s', len(total-1), current, total-1, pat)
            else
                let msg = printf('[>%*d/>%d] %s', len(total-1), current-1, total-1, pat)
            endif
        endif
        if strchars(msg, 1) > (v:echospace + (&cmdheight-1)*&columns)
            let n = v:echospace - 3
            let [n1, n2] = n%2 ? [n/2, n/2] : [n/2-1, n/2]
            let msg = matchlist(msg, '\(.\{'..n1..'}\).*\(.\{'..n2..'}\)')[1:2]->join('...')
        endif
        echo msg
        return ''
    endfu

    nmap n <plug>(n)<plug>(search_index)
    nmap N <plug>(N)<plug>(search_index)
    nno <plug>(n) n
    nno <plug>(N) N
    nno <expr> <plug>(search_index) <sid>search_index()

`searchcount()` won't show a total amount of matches greater than 1000.  If that's not enough, increase `s:MAXCOUNT`.
And it will stop trying to compute the number of matches after half-a-second.  If that's too long, decrease `s:TIMEOUT`.

Note that increasing `s:MAXCOUNT` and `s:TIMEOUT` may have a negative impact on Vim's performance.  The values used in the previous snippet work for me; they may or may not work for you.  I guess it depends on the machine you're using and/or on the patterns you're usually looking for.  Take that into consideration before setting these parameters.

You can improve the performance by rewriting the code in Vim9 script:

    vim9script

    const MAXCOUNT = 1000
    const TIMEOUT = 500

    augroup index_after_slash | au!
        au CmdlineLeave /,\? IndexAfterSlash()
    augroup END

    def IndexAfterSlash()
        if getcmdline() == '' || state() =~# 'm'
            return
        endif
        timer_start(0, {-> mode() =~# '[nv]' ? SearchIndex() : 0})
    enddef

    def SearchIndex(): string
        let incomplete: number
        let total: number
        let current: number
        let result: dict<any>
        try
            result = searchcount({'maxcount': MAXCOUNT, 'timeout': TIMEOUT})
            current = result.current
            total = result.total
            incomplete = result.incomplete
        catch
            echohl ErrorMsg | echom v:exception | echohl NONE
            return ''
        endtry
        let msg = ''
        let pat = getreg('/')->substitute('\%x00', '^@', 'g')
        if incomplete == 0
            msg = printf('[%*d/%d] %s', len(total), current, total, pat)
        elseif incomplete == 1 # recomputing took too much time
            msg = printf('[?/??] %s', pat)
        elseif incomplete == 2 # too many matches
            if result.total == (result.maxcount + 1) && result.current <= result.maxcount
                msg = printf('[%*d/>%d] %s', len(total - 1), current, total - 1, pat)
            else
                msg = printf('[>%*d/>%d] %s', len(total - 1), current - 1, total - 1, pat)
            endif
        endif
        if strchars(msg, 1) > (v:echospace + (&cmdheight - 1) * &columns)
            let n = v:echospace - 3
            let n1 = n % 2 ? n / 2 : n / 2 - 1
            let n2 = n / 2
            let matchlist = matchlist(msg, '\(.\{' .. n1 .. '}\).*\(.\{' .. n2 .. '}\)')
            msg = matchlist[1] .. '...' .. matchlist[2]
        endif
        echo msg
        return ''
    enddef

    nmap n <plug>(n)<plug>(search_index)
    nmap N <plug>(N)<plug>(search_index)
    nno <plug>(n) n
    nno <plug>(N) N
    nno <expr> <plug>(search_index) <sid>SearchIndex()

---

For more info, see:

 - [`:h searchcount()`](https://vimhelp.org/eval.txt.html#searchcount())
 - [`:h vim9`](https://vimhelp.org/vim9.txt.html)
 - [`:h :def`](https://vimhelp.org/vim9.txt.html#:def)