Reduce memory usage on heroku hosted

We run metabase on a heroku standard 1x dyno which gives us 1gb of memory. It appears that metabase will use all of that, and a little more regardless of whether it's being used at the time or not. This is leading to R14 memory issues and we also experience a significant amount of freezing and slow processing. Surely this isn't right?

I have seen several old (~3 + year old) threads on this topic but nothing recently that would address the issue. I have also looked into Heroku's own docs on JVM and the only suggestion was to add

heroku config:set JAVA_TOOL_OPTIONS=-XX:+UseContainerSupport

but this has made no difference.

Are there any other suggestions for this.
We did think about upgrading the dyno further but I can see from others that JVM will just use any and all memory in the same manner.

Running the latest 0.45.3 build

Diagnostic Info

{
  "browser-info": {
    "language": "en-GB",
    "platform": "MacIntel",
    "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36",
    "vendor": "Google Inc."
  },
  "system-info": {
    "file.encoding": "UTF-8",
    "java.runtime.name": "OpenJDK Runtime Environment",
    "java.runtime.version": "11.0.18+10-LTS",
    "java.vendor": "Azul Systems, Inc.",
    "java.vendor.url": "http://www.azul.com/",
    "java.version": "11.0.18",
    "java.vm.name": "OpenJDK 64-Bit Server VM",
    "java.vm.version": "11.0.18+10-LTS",
    "os.name": "Linux",
    "os.version": "4.4.0-1104-aws",
    "user.language": "en",
    "user.timezone": "Etc/UTC"
  },
  "metabase-info": {
    "databases": [
      "h2",
      "postgres"
    ],
    "hosting-env": "heroku",
    "application-database": "postgres",
    "application-database-details": {
      "database": {
        "name": "PostgreSQL",
        "version": "13.9 (Ubuntu 13.9-1.pgdg20.04+1)"
      },
      "jdbc-driver": {
        "name": "PostgreSQL JDBC Driver",
        "version": "42.5.0"
      }
    },
    "run-mode": "prod",
    "version": {
      "date": "2023-02-19",
      "tag": "v0.45.3",
      "branch": "release-x.45.x",
      "hash": "070f57b"
    },
    "settings": {
      "report-timezone": null
    }
  }
}

What does UseContainerSupport mean?

This article can be more helpful on how to change the JVM RAM :

Thank you for this Tony. I have been through this but any options I have control over do not appear to make any difference to the memory used. Either they are ignored or are incorrect.

How many concurrent users do you have? how many and how big are your databases? although Metabase can run with as little as 256mb of RAM, it will get killed very fast when you start using it for a production workload

about 2 users during daylight hours and db is under 100mb.
it's accessing data from a db of around 5gb but that shouldn't be affecting anything

Can you apply scheduled reboots or recycle the container every certain amount of hours?

Even with a reboot, the ram jumps up immediately. It's not a gradual increase over a day unfortunately so scheduled reboots wouldn't do much.

You can see on the image I shared, on the very far right there's a blue box. that was a reboot

you have just 1 database is that correct?

Yes, that's correct

Hi,

I have the same issue. Heroku offers a server with 1Gb of RAM for 50$/month but even without using metabase, it uses more than the available memory.

My only way to fix this is with vertical scaling, by using the next server size from heroku, with 2.5Gb of RAM but it costs 250$/month
Indeed, horizontal scaling won't reduce the load per instance :cry:

I'm running metabase image v0.47.7 (but had similar problem with v0.45.3, even if it was consuming a bit less RAM) with the following JAVA_OPTS

# We need to override the $JAVA_OPTS and give it a slightly lower memory limit
# because Heroku tends to think we can use more memory than we actually can.
JAVA_OPTS="$JAVA_OPTS -XX:+UnlockExperimentalVMOptions"
JAVA_OPTS+="- XX:+UseCGroupMemoryLimitForHeap"
# Tell the JVM to use container info to set heap limit -- see https://devcenter.heroku.com/articles/java-memory-issues#configuring-java-to-run-in-a-container
JAVA_OPTS+=" -XX:+UseContainerSupport"
# Disable limit to amount of time spent in GC. Better slow than not working at all
JAVA_OPTS+=" -XX:-UseGCOverheadLimit"
# Use 32-bit pointers. Reduces memory usage
JAVA_OPTS+=" -XX:+UseCompressedOops"
# Same as above. See also http://blog.leneghan.com/2012/03/reducing-java-memory-usage-and-garbage.html
JAVA_OPTS+=" -XX:+UseCompressedClassPointers"
# Skip bytecode verification, the Heroku buildpack comes from us so it's already verified. Speed up launch slightly
JAVA_OPTS+=" -Xverify:none"
# G1GC seems to use slightly less memory in my testing...
JAVA_OPTS+=" -XX:+UseG1GC"
# Especially when used in combination with string deduplication
JAVA_OPTS+=" -XX:+UseStringDeduplication"

# Other Java options
# Run in server mode. This is the default for 64-bit JVM
JAVA_OPTS+=" -server"
# don't try to start AWT. Not sure this does anything but better safe than wasting memory
JAVA_OPTS+=" -Djava.awt.headless=true"
# Use UTF-8
JAVA_OPTS+=" -Dfile.encoding=UTF-8"

All those parameters are old. I suggest you make your own ones instead of using those which mostly not apply by now