Fastapi: Running FastAPI from a Ubuntu 20.04 Systemd service cpu hog 80-100%

Created on 20 Jul 2020  路  2Comments  路  Source: tiangolo/fastapi

First check

  • [x ] I added a very descriptive title to this issue.
  • [x ] I used the GitHub search to find a similar issue and didn't find it.
  • [x ] I searched the FastAPI documentation, with the integrated search.
  • [x ] I already searched in Google "How to X in FastAPI" and didn't find any information.
  • [x] I already read and followed all the tutorial in the docs and didn't find an answer.
  • [x ] I already checked if it is not related to FastAPI but to Pydantic.
  • [ X] I already checked if it is not related to FastAPI but to Swagger UI.
  • [X ] I already checked if it is not related to FastAPI but to ReDoc.
  • [ X] After submitting this, I commit to one of:

    • Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.

    • I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.

    • Implement a Pull Request for a confirmed bug.

========================================================

Might be a little off topic, but running a FastAPI program from a Ubuntu 20.04 Systemd Service pegs the CPU around 80-100%. With out any queries being preformed. Using htop to view cpu usage by process. This has happened with 2 different API that I have written using Fast API. I acknowledge that this might not be a FastAPI issue. I am using uvicorn.run() to start the web server in main.py

When i just run the script as "python main.py" from the CLI there is almost 0 CPU Usage

htop cpu usage with 0 API Queries

  1  [                                                                                  0.0%]   Tasks: 36, 68 thr; 2 running
  2  [|                                                                                 0.7%]   Load average: 0.70 0.74 0.63 
  3  [|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||        83.4%]   Uptime: 06:33:28
  4  [|                                                                                 0.7%]
  Mem[||||||||||||||                                                              521M/7.78G]
  Swp[                                                                                 0K/0K]

    PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
   2181 root       20   0 40716 31408 12884 R 83.4  0.4 14:10.43 /opt/api/env/bin/python /opt/api/src/main.py
   2202 root       20   0 47212 32556 14640 S  0.7  0.4  0:01.78 /opt/api/env/bin/python -c from multiprocessing.spawn import spawn_main; spawn_main(tracker_fd=5, pipe_handle=7) --mu

systemd service file
systemctl start api | systemctl stop api

/lib/systemd/system/api.service 
[Unit]
Description=My API
After=multi-user.target
[email protected]

[Service]
Type=simple
ExecStart=/opt/api/env/bin/python /opt/api/src/main.py
StandardOutput=file:/opt/api/logs/api.log
StandardInput=tty-force
#Restart=always

[Install]
WantedBy=multi-user.target

Config File: config.py

api = {
    "host": "0.0.0.0",
    "port": 50000,
    "reload": True,
    "workers": 1,
    "log_level": "info",
    "debug": False
}

Main.py

import api
import uvicorn
import sys
import traceback

# Configuration File
import config as cfg

if __name__ == '__main__':
    print(f'Starting API Server: {cfg.api["host"]}:{cfg.api["port"]}\n')

    try:
        uvicorn.run(
            "api:app",
            host=cfg.api["host"],
            port=cfg.api["port"],
            workers=cfg.api["workers"],
            log_level=cfg.api["log_level"],
            reload=cfg.api["reload"],
            debug=cfg.api["debug"]
        )
    except KeyboardInterrupt:
        print(f'\nExiting\n')
    except Exception as e:
        print(f'Failed to Start API')
        print('='*100)
        traceback.print_exc(file=sys.stdout)
        print('='*100)
        print('Exiting\n')
    print(f'\n\n')

api.py
Note lrn is a module that opens a tcp socket to a server, send a query, and get a response.

from fastapi import FastAPI
import uvicorn
from lrn import SSLRN

host = 'myhost.com'
port = 123456

lrn = SSLRN()
lrn.set_host(host, port)


######################
# Fast API
######################
app = FastAPI(
    title="API",
    description="API",
    version="1.0"
)


#####################
# Endpoints
#####################
@app.get("/ep")
@app.post("/ep")
async def ep_get(number: str= None, apikey: str = None):
    result = lrn.query_single(number)
    return lrn.parser(result)

Module Versions

pip freeze
click==7.1.2
fastapi==0.59.0
h11==0.9.0
httptools==0.1.1
install==1.3.3
mysql-connector-python==8.0.21
pkg-resources==0.0.0
protobuf==3.12.2
pydantic==1.6.1
six==1.15.0
starlette==0.13.4
uvicorn==0.11.5
uvloop==0.14.0
websockets==8.1
question

All 2 comments

Aghhhh!!! (Facepalm) I left uvicorn reload=True enabled.

I worked on this for 4 hours, then only realizing what I did 5 mins after posting this issue.
I hope my frustration helps someone else in the future.... Thanks for letting me vent my issue on github.

Changed the config.py to the following

# Fast API Config
# Make sure to set reload = False 
#   If you don't you will get 80-100% CPU Usage on a single core
#   When running from a ubuntu systemd process
# reload = True only for dev enviroments
api = {
    "host": "0.0.0.0",
    "port": 50000,
    "reload":  False,
    "workers": 1,
    "log_level": "info",
    "debug": False
}

Thanks for reporting back and closing the issue @esundberg :+1: . And yeah, it happens sometimes :sweat_smile: :shrug:

Was this page helpful?
0 / 5 - 0 ratings