How to get 128 vCPUs on Koyeb?

I’m deploying a web app where some livestream features are present. However, I’m encountering timeout issues when running the app on Koyeb even though it works on my local machine fine.
I did some research and saw that a vCPU is totally different than a CPU. My CPU is a AMD Ryzen 7 3700X 8-Core Processor. After doing the conversion to vCPU, I found this:
(16 Threads x 8 Cores) x 1 CPU = 128 vCPU
I checked in Koyeb plans tab but I wasn’t able to find an option that would allow me to run the app at 128 vCPU.
Can I get some help or insights please? Thanks!

Do the graphs indicate that the CPU is the bottleneck? Is it fully utilized? The problem might be somewhere else.
Are you getting HTTP timeouts?

A vCPU, is simply a virtualized CPU. I’m not sure why you multiplied the number of threads by the number of cores. A 2XLarge or 3XLarge will probably match the performance of your Ryzen 7 3700x.

Thanks for your reply!
I got the conversion from this website.
Here is the log of the error I’m getting:

10.250.0.20 - - [28/Jan/2025:05:47:42 +0000] "GET /video_feed HTTP/1.1" 500 0 "-" "-"
[2025-01-28 05:47:42 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:522)
[2025-01-28 05:47:42 +0000] [522] [ERROR] Error handling request /video_feed
Traceback (most recent call last):
  File "/workspace/.heroku/python/lib/python3.12/site-packages/gunicorn/workers/sync.py", line 134, in handle
    self.handle_request(listener, req, client, addr)
  File "/workspace/.heroku/python/lib/python3.12/site-packages/gunicorn/workers/sync.py", line 177, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/.heroku/python/lib/python3.12/site-packages/flask/app.py", line 2552, in __call__
    return self.wsgi_app(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/.heroku/python/lib/python3.12/site-packages/flask/app.py", line 2529, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/.heroku/python/lib/python3.12/site-packages/flask/app.py", line 1823, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/.heroku/python/lib/python3.12/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/cleanapp.py", line 366, in video_feed
    redirect(url_for('video_feed'))
             ^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/.heroku/python/lib/python3.12/site-packages/flask/helpers.py", line 256, in url_for
    return current_app.url_for(
           ^^^^^^^^^^^^^^^^^^^^
  File "/workspace/.heroku/python/lib/python3.12/site-packages/flask/app.py", line 2023, in url_for
    rv = url_adapter.build(  # type: ignore[union-attr]
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/.heroku/python/lib/python3.12/site-packages/werkzeug/routing/map.py", line 922, in build
    rv = self._partial_build(endpoint, values, method, append_unknown)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/.heroku/python/lib/python3.12/site-packages/werkzeug/routing/map.py", line 801, in _partial_build
    rv = self._partial_build(
         ^^^^^^^^^^^^^^^^^^^^
  File "/workspace/.heroku/python/lib/python3.12/site-packages/werkzeug/routing/map.py", line 813, in _partial_build
    if rule.suitable_for(values, method):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/.heroku/python/lib/python3.12/site-packages/werkzeug/routing/rules.py", line 869, in suitable_for
    def suitable_for(
    
  File "/workspace/.heroku/python/lib/python3.12/site-packages/gunicorn/workers/base.py", line 204, in handle_abort
    sys.exit(1)
SystemExit: 1

Hi @Abdoulaye_Diallo,
It looks like your worker timeouts when handling /video_feed path. Can you share the code of this function?
Maybe it does some long operations?

Indeed, according to ChatGPT, the function does some long operations. However, it works fine on all local machines I tested the app on. Here is the code for reference:

def imageflow_demo_yolo_UI_integrated(args):
    print('real path', args.path, 'demo', args.demo)
    if args.path.isdigit():
        cap = cv2.VideoCapture(args.camid)
    else:
        cap = cv2.VideoCapture(args.path)
    width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)  # float
    height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)  # float
    fps = cap.get(cv2.CAP_PROP_FPS)
    
    print('step1 ok')
    if not os.path.exists(args.path):
        print('path does not exist')
    else:
        print('victory')

    if not cap.isOpened():
        print('path exist but cannot be opened')
    else:
        print('victoryy')

    print('about to start')
    while True:
        print('CV is reading')
        ret_val, frame = cap.read()

        if not ret_val:
            print('restarting CV')
            print('path', args.path, 'demo', args.demo)
            if args.path.isdigit():
                cap = cv2.VideoCapture(int(args.path))
            else:
                cap = cv2.VideoCapture(args.path)
            width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)  # float
            height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)  # float
            fps = cap.get(cv2.CAP_PROP_FPS)
            print('unsucessful extraction of frame ... ')

        if ret_val:
            ret, buffer = cv2.imencode('.jpg', frame)
            frame = buffer.tobytes()
            print('successfully extracted frame ...')
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')    

video_source = None
lst_sources = {}
ind=0
current_time = None
@app.route('/video_feed')
def video_feed():
    global video_source
    global current_time
    global ind

    # Get the URL from the query parameters
    video_source = request.args.get('url')  
    args = arti_parser(video_source).parse_args()
    print('test', args.path, args.experiment_name)
    
    # keep a list of all the new cameras added to the system
    if args.path not in lst_sources:
        lst_sources[args.path]=ind
        ind+=1

    print("passing with", args.path)
    if not args.experiment_name:
        args.experiment_name ="exp_name"

    file_name = os.path.join("exp_dir", args.experiment_name)
    os.makedirs(file_name, exist_ok=True)

    logger.info("Args: {}".format(args))
    logger.info("Model Summary: No CV model::reading frames")

    print(args.path)
    print('dartagnan')

    # None is between quotes becasue of line 29. If str(None) is None in quotes
    while args.path=='None':
        redirect(url_for('video_feed'))

    return Response(imageflow_demo_yolo_UI_integrated(args),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

I think it should be if instead of while and you should return return redirect(url_for('video_feed'))

    if args.path=='None':
        return redirect(url_for('video_feed'))