HoJ bot : Heroku Memory quota exceed

Fellow Julians : I was trying to put HoJ(Humans of Julia) bot on heroku, but memory quota exceeded issue keeps arising. Yeah, atleast with the free tier that’s the case.
Though I think in general it would be awesome to be able to deploy Julia APIs to Heroku, it really is a lot nicer than using AWS, especially for small projects. Also,lot of new users who want to try julia, heroku /netlify are much more accessible.
HoJ bot is new and comparatively small project as of now, so shouldn’t have had an issue like this in my opinion. We need some hacky tricks here lol or smart optimizations I guess
Heroku free tier has only 512mb in memorytotal
geniejl test app that works and says " hi!! there"
https://testgenieapp.herokuapp.com/
I found that example app from a tutorial https://towardsdatascience.com/deploying-julia-projects-on-heroku-com-eb8da5248134

See e.g. Deploying to Heroku with Buildpacks · Genie - The Highly Productive Julia Web Framework

What to do?
Relevant links:

2021-05-15T08:07:32.000000+00:00 app[api]: Build started by user ab669522@gmail.com
2021-05-15T08:14:39.448377+00:00 app[api]: Deploy e282600d by user ab669522@gmail.com
2021-05-15T08:14:39.448377+00:00 app[api]: Release v5 created by user ab669522@gmail.com
2021-05-15T08:14:39.461252+00:00 app[api]: Scaled to web@1:Free by user ab669522@gmail.com
2021-05-15T08:14:55.000000+00:00 app[api]: Build succeeded
2021-05-15T08:15:15.116383+00:00 heroku[web.1]: Starting process with command `ENABLE_WARM_UP=0 script/run.sh`
2021-05-15T08:15:17.881502+00:00 app[web.1]: Sat 15 May 2021 08:15:17 AM UTC: Starting HoJBot...
2021-05-15T08:15:23.491540+00:00 app[web.1]: Precompiling project...
2021-05-15T08:15:25.691892+00:00 heroku[web.1]: Process running mem=513M(100.3%)
2021-05-15T08:15:25.695952+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2021-05-15T08:15:38.026418+00:00 app[web.1]:   ✓ LibSSH2_jll
2021-05-15T08:15:40.537176+00:00 heroku[web.1]: Process running mem=1280M(250.0%)
2021-05-15T08:15:40.595135+00:00 heroku[web.1]: Error R15 (Memory quota vastly exceeded)
2021-05-15T08:15:40.600913+00:00 heroku[web.1]: Stopping process with SIGKILL
2021-05-15T08:15:40.626446+00:00 heroku[web.1]: Process running mem=917M(179.2%)
2021-05-15T08:15:40.751662+00:00 heroku[web.1]: Process exited with status 137
2021-05-15T08:15:40.823925+00:00 heroku[web.1]: State changed from starting to crashed
2021-05-15T08:15:40.835675+00:00 heroku[web.1]: State changed from crashed to starting
2021-05-15T08:16:10.958837+00:00 heroku[web.1]: Starting process with command `ENABLE_WARM_UP=0 script/run.sh`
2021-05-15T08:16:13.581186+00:00 app[web.1]: Sat 15 May 2021 08:16:13 AM UTC: Starting HoJBot...
2021-05-15T08:16:18.898049+00:00 app[web.1]: Precompiling project...
2021-05-15T08:16:21.692931+00:00 heroku[web.1]: Process running mem=520M(101.6%)
2021-05-15T08:16:21.695153+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2021-05-15T08:16:36.022114+00:00 app[web.1]:   ✓ LibSSH2_jll
2021-05-15T08:16:36.918886+00:00 app[web.1]:   ✓ LRUCache
2021-05-15T08:16:39.212718+00:00 heroku[web.1]: Process running mem=1280M(250.0%)
2021-05-15T08:16:39.356994+00:00 heroku[web.1]: Error R15 (Memory quota vastly exceeded)
2021-05-15T08:16:39.360248+00:00 heroku[web.1]: Stopping process with SIGKILL
2021-05-15T08:16:39.398651+00:00 heroku[web.1]: Process running mem=1003M(195.9%)
2021-05-15T08:16:39.453097+00:00 heroku[web.1]: Error R15 (Memory quota vastly exceeded)
2021-05-15T08:16:39.456142+00:00 heroku[web.1]: Stopping process with SIGKILL
2021-05-15T08:16:39.548497+00:00 heroku[web.1]: Process exited with status 137
2021-05-15T08:16:39.604996+00:00 heroku[web.1]: State changed from starting to crashed
2021-05-15T08:45:51.525249+00:00 heroku[web.1]: State changed from crashed to starting
2021-05-15T08:46:18.324906+00:00 heroku[web.1]: Starting process with command `ENABLE_WARM_UP=0 script/run.sh`
2021-05-15T08:46:20.648526+00:00 app[web.1]: Sat 15 May 2021 08:46:20 AM UTC: Starting HoJBot...
2021-05-15T08:46:26.026701+00:00 app[web.1]: Precompiling project...
2021-05-15T08:46:33.885659+00:00 heroku[web.1]: source=web.1 dyno=heroku.213526618.d0297e43-e320-4302-9296-0ff9ba2e068f sample#memory_total=902.38MB sample#memory_rss=447.63MB sample#memory_cache=0.12MB sample#memory_swap=454.62MB sample#memory_pgpgin=289848pages sample#memory_pgpgout=175224pages sample#memory_quota=512.00MB
2021-05-15T08:46:33.931085+00:00 heroku[web.1]: Process running mem=902M(176.2%)
2021-05-15T08:46:33.934188+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2021-05-15T08:46:35.096085+00:00 app[web.1]:   ✓ LibSSH2_jll
2021-05-15T08:46:40.333850+00:00 heroku[web.1]: Process running mem=1279M(249.9%)
2021-05-15T08:46:40.594226+00:00 heroku[web.1]: Error R15 (Memory quota vastly exceeded)
2021-05-15T08:46:40.600974+00:00 heroku[web.1]: Stopping process with SIGKILL
2021-05-15T08:46:40.623293+00:00 heroku[web.1]: Process running mem=923M(180.4%)
2021-05-15T08:46:40.677844+00:00 heroku[web.1]: Error R15 (Memory quota vastly exceeded)
2021-05-15T08:46:40.681576+00:00 heroku[web.1]: Stopping process with SIGKILL
2021-05-15T08:46:40.794367+00:00 heroku[web.1]: Process exited with status 137
2021-05-15T08:46:40.868352+00:00 heroku[web.1]: State changed from starting to crashed
2021-05-15T08:46:40.876778+00:00 heroku[web.1]: State changed from crashed to starting
2021-05-15T08:47:20.422172+00:00 heroku[web.1]: Starting process with command `ENABLE_WARM_UP=0 script/run.sh`
2021-05-15T08:47:23.854809+00:00 app[web.1]: Sat 15 May 2021 08:47:23 AM UTC: Starting HoJBot...
2021-05-15T08:47:32.887358+00:00 app[web.1]: Precompiling project...
2021-05-15T08:47:42.730306+00:00 heroku[web.1]: source=web.1 dyno=heroku.213526618.d5201220-4b74-4f21-9fe0-95b70ba70160 sample#memory_total=845.57MB sample#memory_rss=511.88MB sample#memory_cache=0.12MB sample#memory_swap=333.57MB sample#memory_pgpgin=228850pages sample#memory_pgpgout=100334pages sample#memory_quota=512.00MB
2021-05-15T08:47:42.803320+00:00 heroku[web.1]: Process running mem=845M(165.1%)
2021-05-15T08:47:42.805894+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2021-05-15T08:47:59.119587+00:00 heroku[web.1]: source=web.1 dyno=heroku.213526618.d5201220-4b74-4f21-9fe0-95b70ba70160 sample#memory_total=953.70MB sample#memory_rss=511.83MB sample#memory_cache=0.09MB sample#memory_swap=441.78MB sample#memory_pgpgin=307986pages sample#memory_pgpgout=181021pages sample#memory_quota=512.00MB
2021-05-15T08:47:59.170387+00:00 heroku[web.1]: Process running mem=953M(186.3%)
2021-05-15T08:47:59.176075+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2021-05-15T08:48:17.141463+00:00 heroku[web.1]: source=web.1 dyno=heroku.213526618.d5201220-4b74-4f21-9fe0-95b70ba70160 sample#load_avg_1m=3.49
2021-05-15T08:48:17.186776+00:00 heroku[web.1]: source=web.1 dyno=heroku.213526618.d5201220-4b74-4f21-9fe0-95b70ba70160 sample#memory_total=938.26MB sample#memory_rss=478.76MB sample#memory_cache=0.39MB sample#memory_swap=459.11MB sample#memory_pgpgin=452950pages sample#memory_pgpgout=354304pages sample#memory_quota=512.00MB
2021-05-15T08:48:17.189448+00:00 heroku[web.1]: Process running mem=938M(183.2%)
2021-05-15T08:48:17.191342+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2021-05-15T08:48:16.980271+00:00 app[web.1]:   ✓ LRUCache
2021-05-15T08:48:17.037826+00:00 app[web.1]:   ✓ Grisu
2021-05-15T08:48:18.128215+00:00 app[web.1]:   ✓ CompilerSupportLibraries_jll
2021-05-15T08:48:18.138368+00:00 app[web.1]:   ✓ LibSSH2_jll
2021-05-15T08:48:20.797178+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
2021-05-15T08:48:20.844899+00:00 heroku[web.1]: Stopping process with SIGKILL
2021-05-15T08:48:21.478180+00:00 heroku[web.1]: Process exited with status 137
2021-05-15T08:48:21.545752+00:00 heroku[web.1]: State changed from starting to crashed


Did you use GitHub - mbauman/heroku-buildpack-julia: Heroku buildpack to run Julia?

I use this one : GitHub - Optomatica/heroku-buildpack-julia: Heroku buildpack to run Julia
mcbauman’s one hasn’t been updated for quite sometime now: GitHub - mbauman/heroku-buildpack-julia: Heroku buildpack to run Julia

I also ran into pricing issues with Heroku. Once you need more memory, pricing goes up way too quick. I moved to fly.io, which is much cheaper and also easy to set up with Julia. Let me know if you want to have some example code. I‘m running 2 GB ram for 10 dollar per month now.

1 Like

I would like to view that example code if you still have it.

Sorry for taking a few days to respond. I wasn’t near a computer this weekend. I cannot share the full code, but can share the most important for my configuration which runs Makie + HTTP on Fly. It uses about 800 MB of RAM and takes only a few seconds to start thanks to PackageCompiler.

MyApp

module MyApp

using CairoMakie
using HTTP
[...]

function serve_backend(; host=HOST, server=nothing)
    port = BACKEND_PORT
    println("Running server at http://$host:$port")    
    socket = isnothing(server) ? server_socket(host, port) : server
    r = router()
    println("Created router")
    return httpserve(r, host, port; server=socket)
end

end # module

scripts/start_server.jl

using MyApp: serve_backend

host = "0.0.0.0"
serve_backend(; host)

scripts/precompile.jl

# Don't use MyApp in this script because that would mean a PackageCompiler rebuild every time code is changed.

using CairoMakie
using HTTP
using Sockets
using Makie:
      FileIO,
      lines

function get_ping(req::HTTP.Request)
    return HTTP.Response(200, "pong")
end

const ROUTER = HTTP.Router()
HTTP.@register(ROUTER, "GET", "/ping", get_ping)

function server_socket(host::String, port::Integer)::Sockets.TCPServer
    socket = listen(Sockets.InetAddr(parse(Sockets.IPAddr, host), port))
    return socket
end

host = string(Sockets.localhost)::String
port = 8128
server = server_socket(host, port)
@async HTTP.serve(ROUTER, host, port; server)

response = HTTP.get("http://$host:$port/ping")
@assert response.status == 200
close(server)

fig = lines(1:10, 1:10)
filename = "tmp.svg"
# A lot of plotting logic is only called when saving.
FileIO.save(filename, fig)
rm(filename)

scripts/compile.jl

using PackageCompiler:
    create_sysimage,
    default_app_cpu_target
using Pkg: dependencies

function direct_dependencies()
    deps = dependencies()
    package_infos = [last(pair) for pair in deps]
    filter!(p -> p.is_direct_dep, package_infos)
    return [p.name for p in package_infos]
end

packages = direct_dependencies()

project = "."

sysimage_path = joinpath(project, "img.so")
cpu_target = default_app_cpu_target()
precompile_execution_file = joinpath(project, "scripts/precompile.jl")

@time create_sysimage(packages; project, sysimage_path, cpu_target, precompile_execution_file)

Dockerfile

# Nix and the default Ubuntu don't really save memory usage anyway.
# My own docker image at least saves a lot of package downloading.
FROM rikhuijzer/rug-julia-image

RUN mkdir /app
WORKDIR /app

# Add PackageCompiler to the global environment.
# and force downloading of MKL artifact.
# This could be replaced by PackageCompiler `include_lazy_artifacts=true`.
RUN julia -e 'using Pkg: PackageSpec, add; \
  p1 = PackageSpec(; name="PackageCompiler", version="1"); \
  p2 = PackageSpec(; name="MKL_jll"); \
  add([p1, p2]); \
  using MKL_jll'

COPY Project.toml /app/
RUN mkdir -p /app/src/; \
  echo 'module MyApp end' > /app/src/MyApp.jl ; \
  julia --project -e 'using Pkg: instantiate; instantiate()'
COPY scripts/compile.jl /app/scripts/
COPY scripts/precompile.jl /app/scripts/
RUN julia --project scripts/compile.jl

COPY src/ /app/src/
COPY scripts/start_server.jl /app/scripts/

CMD ["julia", "--project", "--sysimage", "img.so", "scripts/start_server.jl"]

.gitlab-ci.yml

image: julia/1.6-buster

workflow:

stages:
  - build-deploy

job 1:
  stage: build-deploy
  script:
      - julia --project -e 'import Pkg; Pkg.instantiate()'
      - julia --project -e 'import Pkg; Pkg.test()'
      # Build speed is mostly based on network bandwidth and single threaded performance.
      - flyctl deploy --build-only --remote-only --no-cache
1 Like