How to Install Nexus Repository OSS on Ubuntu 24.04 — Self-Hosted Artifact Manager
A central artifact repository is the connective tissue of any serious software team. It caches your dependencies, hosts your internal libraries, stores your Docker images, and enforces the quality gates between "built" and "released." Sonatype Nexus Repository OSS is the open-source reference implementation of that role and has been running in production at millions of companies since 2008. This guide walks you through installing Nexus Repository 3 on an Ubuntu 24.04 LTS VPS, from JDK install through multi-format repositories, LDAP integration, cleanup policies, and a production-grade Nginx reverse proxy with TLS.
Want a ready-made DevOps stack? The CloudCore Professional VPS at EUR 19.99/month gives you the headroom to run Nexus alongside Jenkins and Gitea on the same box. Pre-installed snapshots are available for faster rollouts.
Table of Contents
What is Nexus Repository?
Nexus Repository is a universal artifact manager built by Sonatype. It sits between your developers, your CI system, and public package registries, acting as a proxy cache, a hosted repository, and a group aggregator for more than 30 component formats. In the OSS edition you get first-class support for Maven (Java), npm (Node.js), Docker (OCI images), PyPI (Python), NuGet (.NET), Helm (Kubernetes charts), RubyGems, Go modules, Conan (C/C++), apt and yum repositories, and generic "raw" repositories for tarballs, firmware images, or anything else you need to serve over HTTP.
Three repository types cover almost every workflow. A hosted repository stores artifacts produced inside your organization — internal libraries, proprietary Docker images, signed release builds. A proxy repository transparently caches a remote registry such as Maven Central, npm Registry, or Docker Hub so your first download hits the internet and every subsequent pull is served from local disk in milliseconds. A group repository merges multiple hosted and proxy repositories behind a single URL, so developers configure one endpoint and Nexus transparently resolves where each artifact actually lives.
Teams use Nexus for everything from cache acceleration on a laptop-sized single-developer install up to cluster deployments serving tens of terabytes of Docker layers to hundreds of CI nodes. On a single Ubuntu 24.04 VPS with 8 GB RAM and a dedicated NVMe blob store, you can comfortably service a 20-engineer team with active Java, Node, Docker, and Python development.
Why Self-Host Nexus Instead of JFrog Cloud or GitHub Packages?
Managed artifact registries are attractive because someone else runs them, but their pricing scales poorly and their integration surface is narrower than it first appears.
- Flat-rate cost vs. per-user / per-GB billing. A CloudCore Professional VPS hosts an unlimited number of users, repositories, and artifacts for EUR 19.99/month. JFrog Artifactory Cloud's Pro tier starts at around USD 98/month for 2 users and grows with storage and transfer. GitHub Packages is "free" for public packages but bills private storage at USD 0.25/GB/month and egress at USD 0.50/GB, which becomes painful once Docker layers are involved.
- No egress surprises. Pulling a 2 GB Docker image 500 times a day from GitHub Packages is over 30 TB of egress per month. On a self-hosted Nexus fronted by Nginx, that traffic stays inside your data centre.
- Format breadth. Nexus OSS supports Maven, Docker, npm, PyPI, NuGet, Helm, apt, yum, raw, Go, RubyGems, Conan, and more in a single service. GitHub Packages is restricted to a smaller set (npm, Maven, NuGet, Docker/Container, RubyGems) and Artifactory splits some formats behind the Pro tier.
- Full audit and retention control. Cleanup policies, proprietary component analysis, repository health check, and LDAP group mapping all run locally, so you can match corporate data-residency and audit requirements without filing a vendor ticket.
- Integrates with the rest of your DevOps stack. If you're also running Jenkins, Gitea, Harbor, or Docker on the same provider, co-locating them eliminates most of your cross-service latency.
- Data sovereignty. Your artifacts — including proprietary code packaged in JARs and Docker images — never leave the VPS. This matters for regulated workloads, pending patents, and clients with contractual on-prem requirements.
Cost Comparison
| Scenario | Artifactory Cloud Pro | GitHub Packages | Self-Hosted Nexus OSS |
|---|---|---|---|
| Monthly base | ~USD 98 (2 users) | Free base + metered | EUR 19.99 (unlimited users) |
| Storage | First 25 GB included, then per-GB | USD 0.25 / GB / month | Limited only by disk |
| Egress | Metered after quota | USD 0.50 / GB | Unmetered on VPS bandwidth |
| Docker registry | Yes (Pro) | Yes | Yes |
| LDAP / SSO | Enterprise tier | GitHub Enterprise only | Included (OSS) |
| Data residency | Provider regions | GitHub regions | Your VPS region |
Prerequisites
Before you begin, make sure you have:
- An Ubuntu 24.04 LTS VPS with root or sudo access
- At least 4 GB of RAM (8 GB+ recommended for teams)
- At least 40 GB of disk space for the application plus a separate volume for blob stores (100 GB+ recommended)
- A domain name pointed at your server's public IP (for TLS)
- SSH access to the server
- Ports 22, 80, and 443 open at the firewall
Recommended Plan: CloudCore Professional — EUR 19.99/month>
The CloudCore Professional plan gives you:>
- 6 vCPU cores
- 12 GB RAM
- 100 GB NVMe SSD
- Unmetered bandwidth>
This comfortably runs Nexus Repository, a reverse proxy, and light CI all on one host. For heavier Docker or multi-TB artifact workloads, add a block-storage volume and mount it as your primary blob store.
Connect to your server:
ssh root@your-server-ipStep 1: Update the System and Install JDK 17
Bring the system up to date and install the supported JDK. Nexus Repository 3.70 and later require Java 17.
sudo apt update && sudo apt upgrade -y
sudo apt install -y openjdk-17-jdk curl wget tar ufwVerify Java:
java -versionExpected output:
openjdk version "17.0.13" 2024-10-15
OpenJDK Runtime Environment (build 17.0.13+11-Ubuntu-2ubuntu124.04)
OpenJDK 64-Bit Server VM (build 17.0.13+11-Ubuntu-2ubuntu124.04, mixed mode, sharing)Set JAVA_HOME globally so Nexus can find it:
echo 'JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' | sudo tee /etc/environment -aIf the kernel was upgraded, reboot:
sudo rebootStep 2: Create the Nexus System User
Nexus must not run as root. Create a dedicated non-login system user that will own the install directory and the working data directory.
sudo useradd --system --no-create-home --shell /bin/bash nexusYou can confirm the user exists:
id nexusExpected output:
uid=997(nexus) gid=997(nexus) groups=997(nexus)Step 3: Download and Extract Nexus Repository 3
Download the latest Unix tarball from Sonatype. The latest-unix.tar.gz URL always redirects to the current GA release.
cd /opt
sudo wget https://download.sonatype.com/nexus/3/latest-unix.tar.gz -O nexus.tar.gz
sudo tar -xvzf nexus.tar.gzThe archive unpacks into two directories:
nexus-3.x.y-z/— the application (read-only, replaced on upgrade)sonatype-work/nexus3/— your persistent data (configuration, blob stores, logs)
sudo ln -s /opt/nexus-3.* /opt/nexusSet ownership on both directories:
sudo chown -R nexus:nexus /opt/nexus /opt/nexus-3.* /opt/sonatype-workTell Nexus to run as the nexus user by editing the run script:
sudo sed -i 's/#run_as_user=""/run_as_user="nexus"/' /opt/nexus/bin/nexus.rcVerify:
cat /opt/nexus/bin/nexus.rcExpected output:
run_as_user="nexus"Step 4: Configure nexus-default.properties
The nexus-default.properties file controls the listening interface, port, and context path. Open it:
sudo nano /opt/nexus/etc/nexus-default.propertiesEdit it so it matches the following:
# Jetty section
application-port=8081
application-host=127.0.0.1
nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-http.xml,${jetty.etc}/jetty-requestlog.xml
nexus-context-path=/Nexus section
nexus-edition=nexus-pro-edition
nexus-features=\
nexus-pro-featureBinding to 127.0.0.1 is deliberate: the only public entry point should be Nginx. If you need Nexus to be reachable directly on the LAN, use the private IP of the interface instead of 0.0.0.0.
Memory Configuration
Nexus JVM heap and direct memory settings live in /opt/nexus/bin/nexus.vmoptions. The defaults (2703 MB heap, 2703 MB direct) are fine for small teams. On a 12 GB VPS, bump them up:
sudo nano /opt/nexus/bin/nexus.vmoptionsRecommended values for 12 GB RAM:
-Xms4G
-Xmx4G
-XX:MaxDirectMemorySize=4G
-XX:+UnlockDiagnosticVMOptions
-XX:+LogVMOutput
-XX:LogFile=../sonatype-work/nexus3/log/jvm.logKeep -Xms equal to -Xmx so the heap is allocated once and never reshaped.
Step 5: Create the systemd Service
Create a unit file so systemctl can manage Nexus and start it on boot.
sudo tee /etc/systemd/system/nexus.service > /dev/null <<'EOF' [Unit] Description=Sonatype Nexus Repository After=network.target[Service] Type=forking LimitNOFILE=65536 ExecStart=/opt/nexus/bin/nexus start ExecStop=/opt/nexus/bin/nexus stop User=nexus Group=nexus Restart=on-failure RestartSec=10 TimeoutStartSec=300 TimeoutStopSec=120
[Install] WantedBy=multi-user.target EOF
Reload systemd, enable the service so it starts at boot, and launch it:
sudo systemctl daemon-reload
sudo systemctl enable nexus
sudo systemctl start nexusWatch the startup logs — Nexus takes 60 to 120 seconds to finish its first boot because it initialises the embedded OrientDB/H2 database:
sudo journalctl -u nexus -fYou're ready when you see:
Started Sonatype Nexus OSS 3.71.0-06 -------------------------------------------------
Started Sonatype Nexus OSS 3.71.0-06 on 127.0.0.1:8081
Confirm the service is healthy:
sudo systemctl status nexus
curl -I http://127.0.0.1:8081/Expected HTTP response:
HTTP/1.1 200 OK
Server: Nexus/3.71.0-06 (OSS)Step 6: First Login and Setup Wizard
On first startup, Nexus generates a random administrator password and writes it to a file inside the work directory. Retrieve it:
sudo cat /opt/sonatype-work/nexus3/admin.passwordExpected output (example):
5c2a0b4f-9a10-4e0e-8d1a-eb9f3e6b1234Keep that value handy. Because Nginx isn't configured yet, SSH-tunnel the port to your laptop so you can reach the UI:
ssh -L 8081:127.0.0.1:8081 root@your-server-ipOpen http://localhost:8081 in your browser. Click Sign In (top right), enter username admin and the password you just read from disk.
The wizard walks you through four screens:
admin.password file is deleted automatically.Once the wizard finishes, the /opt/sonatype-work/nexus3/admin.password file is gone. Store the new password in your team secrets manager.
Step 7: Move Blob Stores to a Separate Disk
Artifacts are stored in blob stores under /opt/sonatype-work/nexus3/blobs/. By default there's a single default blob store on the root disk. For any real workload, move blobs to a dedicated volume so your Docker layers and Maven caches don't exhaust the root filesystem.
Attach a block-storage volume to your VPS (via the control panel) and confirm the device name:
lsblkFormat it as ext4, create a mountpoint, and mount it:
sudo mkfs.ext4 /dev/sdb
sudo mkdir -p /srv/nexus-blobs
sudo mount /dev/sdb /srv/nexus-blobs
sudo chown -R nexus:nexus /srv/nexus-blobsPersist the mount in /etc/fstab:
echo '/dev/sdb /srv/nexus-blobs ext4 defaults,nofail 0 2' | sudo tee -a /etc/fstabIn the Nexus UI, go to Server administration and configuration (gear icon) → Repository → Blob Stores → Create blob store. Choose File type, name it docker-blobs, and set path to /srv/nexus-blobs/docker. Repeat for maven-blobs, npm-blobs, etc. Dedicating one blob store per format makes backups and cleanup policies independently tunable.
For very large installs (multi-TB) consider the S3 blob store type and point it at an object-storage endpoint — this is native OSS functionality and costs nothing extra.
Step 8: Create Your Repositories
All repositories are created from gear icon → Repository → Repositories → Create repository. Choose the recipe, then name the repo and pick a blob store.
Maven 2 — Hosted, Proxy, and Group
Create three Maven repos to form a standard triangle:
maven-releases — recipe maven2 (hosted), version policy Release, write policy Disable redeploy, blob store maven-blobs. Used by your CI to publish released artifacts.maven-snapshots — recipe maven2 (hosted), version policy Snapshot, write policy Allow redeploy, blob store maven-blobs. Receives -SNAPSHOT builds.maven-central — recipe maven2 (proxy), remote URL https://repo1.maven.org/maven2/, blob store maven-blobs. Caches Maven Central.maven-public — recipe maven2 (group), member order: maven-releases, maven-snapshots, maven-central. This is the one URL developers put in their settings.xml.Developers then configure a single <mirror> in ~/.m2/settings.xml:
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>https://nexus.example.com/repository/maven-public/</url>
</mirror>Docker — Hosted Registry
Nexus exposes Docker over HTTPS with a dedicated connector port per repository (Docker clients cannot share a hostname+path). The cleanest approach is to put each Docker repo on its own sub-path behind Nginx with a separate HTTP connector.
Create docker-hosted: recipe docker (hosted), HTTP connector 5000, enable Allow anonymous docker pull only if you want public images, blob store docker-blobs.
Log in from any Docker host (after you've got Nginx + TLS in Step 11):
docker login nexus.example.com
docker tag myapp:1.0 nexus.example.com/myapp:1.0
docker push nexus.example.com/myapp:1.0For pulling Docker Hub through Nexus, create docker-hub as a proxy with remote https://registry-1.docker.io and connector port 5001, then a docker-group bundling docker-hosted and docker-hub on connector 5002.
npm — Proxy
npm-proxy — recipe npm (proxy), remote https://registry.npmjs.org, blob store npm-blobs.npm-hosted for internal packages, npm-group combining both.Developers set their registry:
npm config set registry https://nexus.example.com/repository/npm-group/PyPI — Proxy
pypi-proxy — recipe pypi (proxy), remote https://pypi.org/, blob store default (or its own).pypi-hosted + pypi-group.Developers set their index:
pip config set global.index-url https://nexus.example.com/repository/pypi-proxy/simple/Raw — Generic File Hosting
A raw repository behaves like a plain HTTP file server — perfect for Helm tarballs, OS ISOs, firmware, or any artefact that doesn't fit a formal recipe.
Create raw-internal: recipe raw (hosted), blob store default.
Upload with curl:
curl -u admin:password --upload-file build.tar.gz \
https://nexus.example.com/repository/raw-internal/releases/build-1.0.tar.gzStep 9: Configure Cleanup Policies
Blob stores grow fast, especially for snapshot Maven artefacts and Docker layers. Nexus ships with a cleanup subsystem that you wire in two stages: define a policy, then attach it to repositories, then schedule a task that runs it.
gear icon → Repository → Cleanup Policies → Create cleanup policy. A typical Docker policy:
- Name:
docker-30d-prerelease - Format: docker
- Criteria: Last downloaded before 30 days AND Version matches regex
.-rc.|.-alpha.|.-beta.
- Name:
maven-snapshots-14d - Format: maven2
- Criteria: Last updated before 14 days, published status matches
prerelease.
A second critical task is Admin - Compact blob store, which physically reclaims the space after soft-deletes. Schedule it weekly per blob store.
Step 10: LDAP / Active Directory Integration
For team installs, tie Nexus authentication to your existing directory. Go to gear icon → Security → LDAP → Create connection.
Fill in:
- Name:
corporate-ldap - LDAP URL:
ldaps://ldap.example.com:636 - Search base:
dc=example,dc=com - Authentication method: Simple (or Anonymous/DIGEST-MD5 as needed)
- Username:
cn=nexus-bind,ou=service,dc=example,dc=com - Password: the bind user password
- User search base:
ou=people - User subtree: checked
- Object class:
inetOrgPerson(oruserfor AD) - User ID attribute:
uid(orsAMAccountNamefor AD) - Group type: Dynamic Groups, member attribute
memberOf
Next, enable the LDAP realm under gear icon → Security → Realms: drag LDAP Realm from Available to Active.
Finally, map an LDAP group to a Nexus role. Under gear icon → Security → Roles → Create role → External Role Mapping, set source LDAP and map devops-team to the built-in nx-admin privileges. Any user in that LDAP group can now sign in with SSO-style credentials.
Step 11: Nginx Reverse Proxy with TLS
Never expose port 8081 directly. Front Nexus with Nginx, terminate TLS there, and enlarge the upload body size so Docker layers and large JARs push cleanly.
Install Nginx and Certbot:
sudo apt install -y nginx certbot python3-certbot-nginxOpen the firewall:
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enableCreate the site configuration:
sudo tee /etc/nginx/sites-available/nexus > /dev/null <<'EOF'Redirect HTTP to HTTPS
server { listen 80; server_name nexus.example.com; return 301 https://$host$request_uri; }server { listen 443 ssl http2; server_name nexus.example.com;
ssl_certificate /etc/letsencrypt/live/nexus.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/nexus.example.com/privkey.pem;
# Security headers add_header Strict-Transport-Security "max-age=31536000" always; add_header X-Content-Type-Options nosniff; add_header X-Frame-Options SAMEORIGIN;
# Allow large Docker and Maven uploads (up to 5 GB) client_max_body_size 5G; client_body_buffer_size 1M; proxy_request_buffering off;
# Long-running requests (Docker push, large JAR upload) proxy_connect_timeout 300s; proxy_send_timeout 300s; proxy_read_timeout 300s; send_timeout 300s;
# Nexus web UI and REST API location / { proxy_pass http://127.0.0.1:8081; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto "https"; }
# Docker hosted connector on 5000 location /v2/ { proxy_pass http://127.0.0.1:5000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto "https"; } } EOF
Replace nexus.example.com with your actual domain. Enable the site and issue a certificate:
sudo ln -s /etc/nginx/sites-available/nexus /etc/nginx/sites-enabled/
sudo nginx -t
sudo certbot --nginx -d nexus.example.com
sudo systemctl reload nginxCertbot installs a renewal timer automatically; check it with sudo systemctl list-timers | grep certbot.
Test the full stack:
curl -I https://nexus.example.com/Expected:
HTTP/2 200
server: nginxYou can now close the SSH tunnel and point all your tools at https://nexus.example.com/.
Hardening Checklist
- Disable anonymous access unless you intentionally run public mirrors (gear → Security → Anonymous Access).
- Rotate the admin password and create per-human user accounts mapped to roles.
- Enable the audit log (gear → System → Capabilities → Audit).
- Snapshot the blob stores and run the database backup task nightly, replicate the output off-site.
- Pin the JDK at Java 17 — don't auto-upgrade to 21 without testing against the current Nexus release notes at help.sonatype.com.
FAQ
What are the minimum hardware requirements for Nexus Repository OSS?
Sonatype recommends at least 4 GB of RAM and 2 vCPU for Nexus Repository 3. For a team with active Maven and Docker usage, 8 GB of RAM and a dedicated 100 GB+ SSD blob store is more realistic. The JVM itself defaults to 2703 MB max heap plus 2703 MB max direct memory, so with OS overhead you need at least 6 GB to run Nexus comfortably alongside Nginx and your monitoring stack. The CloudCore Professional plan at 12 GB RAM and 100 GB NVMe is the sweet spot for a 10 to 25 developer team.
Do I need to install Java separately?
Yes. Nexus Repository 3.71+ requires Java 17. Install OpenJDK 17 from the Ubuntu repositories before starting Nexus. Older bundles that shipped their own JRE are no longer distributed for new 3.70+ releases. If you must run an older Nexus on a box that also hosts Java 21 services, install both and use update-alternatives or set JAVA_HOME explicitly in /etc/systemd/system/nexus.service via an Environment= line.
Where is the initial admin password stored?
The randomly generated initial admin password is written to /opt/sonatype-work/nexus3/admin.password on first startup. Read it with sudo cat /opt/sonatype-work/nexus3/admin.password. The file is deleted automatically once you complete the setup wizard and set a permanent password. If you lose the password before running the wizard, stop Nexus, delete the work directory's security.json entry, and restart — Sonatype documents this recovery procedure at help.sonatype.com.
How do I back up Nexus Repository?
Use the built-in Admin - Export configuration & metadata for backup task and snapshot the blob store directory. Together, the database export plus the blob stores constitute a full restorable backup. Schedule the task nightly at 01:00, then rsync /opt/sonatype-work/nexus3/backup/ and /srv/nexus-blobs/ to a second server or object storage bucket at 02:00. Restoring is symmetrical: stop Nexus, restore both directories, start Nexus. Because blob stores are append-only with soft-deletes, a one-day RPO is typical.
Can Nexus OSS host Docker images?
Yes. Nexus Repository OSS supports Docker hosted, proxy, and group repositories at no cost. You need to assign each Docker repository its own HTTP/HTTPS connector port (Docker clients don't support path-based routing natively), or use a subdomain / path-routing strategy behind an Nginx reverse proxy as shown in Step 11. For teams that need content signing and vulnerability scanning built in, consider complementing Nexus with Harbor for Docker-specific workflows.
What is the difference between Nexus OSS and Nexus Pro?
Nexus Repository OSS is free and covers Maven, npm, Docker, PyPI, NuGet, raw, and many other formats with full HA-less functionality. Pro adds staging profiles (required for the Maven Central Portal release flow), enterprise LDAP with user sync, high availability clustering, repository replication, multi-tenant repositories, SAML/Crowd SSO, and Sonatype commercial support. Most small-to-mid teams run fine on OSS; Pro makes sense once you need cross-region replication or a validated release-staging workflow.
Why self-host Nexus instead of using JFrog Artifactory Cloud or GitHub Packages?
Self-hosting Nexus gives you flat per-VPS pricing (EUR 19.99/month on the Professional plan) instead of per-user or per-GB egress billing. You keep full control of retention, cleanup, audit logs, and network policy. Artifactory Cloud and GitHub Packages are excellent managed options but become expensive at team scale (GitHub Packages bills USD 0.50/GB egress, which stings on Docker layers), and they tie your artifacts to a vendor. Nexus OSS data is just files on a disk — you can walk away at any time.
Next Steps
Now that Nexus is running, tie it into the rest of your DevOps stack:
- Wire Jenkins into Nexus — Install the Nexus Artifact Uploader and Repository Manager plugins in Jenkins so CI builds publish to
maven-releasesautomatically on tag. Use the Nexus Platform Plugin for IQ policy evaluation if you later upgrade to Lifecycle. - Mirror Docker Hub through Nexus — Configure your Docker daemons with
"registry-mirrors": ["https://nexus.example.com"]in/etc/docker/daemon.jsonto have every pull cached transparently. This dramatically speeds up CI and insulates you from Docker Hub rate limits. - Pair with Harbor for image signing — Run Harbor alongside Nexus when you need Cosign-based signing, Trivy scanning, and image replication policies. Use Nexus for Maven/npm/PyPI and Harbor as your signed-image front door.
- Connect Gitea as your source — Deploy Gitea on the same VPS so your Git → build → artifact workflow stays inside your own infrastructure end to end.
- Install Docker and a build agent — Follow the Docker on Ubuntu guide to add a build runner that pushes images into your new Docker hosted repo.
- Monitor it — Expose the Nexus JMX metrics to Prometheus or point Uptime Kuma at
https://nexus.example.com/service/rest/v1/statusto alert on unreachable instances. - Read the official docs — The canonical reference for every repository format, security feature, and REST endpoint is at help.sonatype.com. Keep the release notes bookmarked; Nexus ships updates roughly monthly.
Build Your DevOps Stack on CloudCore>
Nexus Repository pairs naturally with a CI server, a Git host, and a container registry. The CloudCore Professional plan at EUR 19.99/month gives you the cores and RAM to host all four on one VPS, and our NVMe storage keeps artifact pulls blazing fast.>
- 6 vCPU cores, 12 GB RAM, 100 GB NVMe SSD
- Unmetered bandwidth for unlimited artifact downloads
- Snapshot backups included
- Deploy in under 60 seconds>
Deploy Your CloudCore VPS Now — EUR 19.99/month, no per-user fees, ever.