Skip to main content

Billable Projects & Micro-Project Pricing

How Vibgrate sizes each scanned project into nano, micro, small or standard tiers, bills it as a fraction of a project, and rounds the total down to your billable projects.

Vibgrate Docs

Vibgrate Help

The One-Line Summary

We don't bill every package as a full project. Each scanned project is automatically sized into one of four tiers — nano, micro, small or standard — and billed as a fraction of a project. We total the fractions across your estate and round down to the nearest whole number. That total is your billable projects.

Tagline: We count a Lambda as a tenth of a project.

Why Micro-Project Pricing Exists

Modern repositories — especially serverless monorepos — can contain hundreds of tiny packages. Billing each one as a full project would penalise exactly the multi-stack, monorepo-heavy teams Vibgrate is built for.

A Lambda handler is not the same unit of work as a 200-file service, so we don't charge for it as if it were. The mechanic is measurable, automatic, and transparent — there are no manual exceptions and no support tickets to reclassify a project.

The Four Tiers

A project is placed in the lowest tier whose limits it meets. A project qualifies for a tier when it satisfies at least two of the three limits for that tier. The tiers nest strictly, so a package that earns nano always also earns micro — the smallest-first evaluation simply bills it at the cheapest tier.

TierQualifies on any 2 of 3Billing weightPlain English
Nano< 10 source files · < 1 MB source · < 5 dependencies1/25 of a projectA tiny single-purpose serverless function
Micro< 20 source files · < 2.5 MB source · < 10 dependencies of a projectA serverless function or tiny micro-service
Small< 30 source files · < 5 MB source · < 25 dependencies of a projectA modest component or library
StandardAnything larger1 projectA normal product service or app

The step between adjacent tiers stays small and predictable, so trimming one dependency or splitting one file never produces a large bill swing — and there's no incentive to game a single metric.

How Classification Works

Every scan measures three signals per project:

  1. Source-file count — number of source files in the project.
  2. Source byte size — total size of those source files.
  3. Dependency count — number of declared dependencies in the package manifest.

Why "Any 2 of 3"

A typical Lambda handler — an index file, a few utilities, a handful of tests, and a few dependencies — would fail a strict "fewer than 10 files AND ..." test the moment a test folder grew. Requiring any two of three catches real micro-projects without being defeated by one chatty test folder or one extra dependency.

A criterion only counts when it is a valid measurement: file count must be at least 1, source size must be greater than 0, and a dependency count of 0 is valid (a package may legitimately have no dependencies). A project with no usable metrics is billed as standard — the conservative, full rate.

What Counts as "Source" Size

The size and file-count signals measure source code only. The following are excluded so they can't inflate a genuinely small project past a threshold:

  • Lockfiles and generated manifests: pnpm-lock.yaml, package-lock.json, yarn.lock, bun.lockb, Gemfile.lock, poetry.lock, Pipfile.lock, composer.lock, Cargo.lock, go.sum, gradle.lockfile, deno.lock, and similar.
  • Vendored dependency directories: node_modules, vendor, Pods (CocoaPods), Carthage, and similar — third-party source, not code you maintain.
  • Build-output directories: dist, build, out, .next, .nuxt, .output, .svelte-kit, coverage, bin, obj, .turbo, .cache, and similar.
  • Binary assets — images, fonts, video, audio, archives, and compiled artifacts.

A single pnpm-lock.yaml can exceed 1 MB on its own. Excluding it is why a one-file Lambda with a big lockfile is still correctly billed as nano.

Calculating Billable Projects

billable_raw = (standard_count x 1)
             + (small_count    x 1/3)
             + (micro_count    x 1/10)
             + (nano_count     x 1/25)

billable_projects = floor(billable_raw)   <- always rounded DOWN

The headline number you are billed for is always rounded down to the nearest whole number. Never to nearest; never up.

Worked Examples

Scanned projectsRaw calculationBillable rawBillable
200 micro · 27 small · 20 standard20 + 9 + 2049.049
9 micro0.90.90
1 standard + 5 micro1 + 0.51.51
3 small1.01.01
250 micro25.025.025

The first row is the canonical estimator line: 247 detected -> 49 billable.

Reclassify Gently: Mid-Cycle Changes

A project's tier is re-evaluated on every scan, but billing changes are applied carefully so a bill never rises unexpectedly mid-month:

  • Crossing up a tier (a micro project grows into small): the project keeps its cheaper rate for the rest of the current billing cycle, and the higher rate takes effect from the next cycle. The pending change is flagged in Vibgrate Cloud as a pending upgrade.
  • Crossing down a tier (a project shrinks): the cheaper rate applies immediately — lowering a bill mid-cycle is always fine.

So the classification you see always reflects the latest scan, while the rate you're billed only ever increases at a cycle boundary.

Fairness Guarantees

  1. Billing weight is never risk weight. Nano, micro and small projects roll up fully into DriftScores, the portfolio view, and every risk and compliance report. Only the billing weight is reduced — the CTO dashboard never under-counts risk.
  2. No silent mid-cycle increases. Upward reclassification is deferred to the next cycle and flagged in advance.
  3. Automatic and measurable. There are no manual exceptions, hidden multipliers, or per-customer overrides — the same three signals are applied to every project on every scan.

Where You'll See It

  • CLI (vg scan) — after the drift score, the classification breakdown and a billable line: Classified: {nano} nano · {micro} micro · {small} small · {standard} standard and {total} detected -> {billable} billable.
  • Dashboard — a nano/micro/small/standard breakdown widget with the billable total and any pending upgrades.
  • Pricing estimator — the {total} detected -> {billable} billable headline with the per-tier breakdown. Drag the average project size slider to model a nano-heavy or standard-heavy estate.
  • Billing APIusage.projects includes billableProjects (floored), billableProjectsRaw, per-tier counts, and a per-repository breakdown.

FAQ

I have a serverless monorepo with hundreds of functions. Will I be billed for all of them? No. Each function is measured automatically and billed as a fraction of a project — a typical Lambda counts as a tenth. We total the fractions and round down, so 247 detected projects might be just 49 billable.

Does a big lockfile push my project into a higher tier? No. Size is measured on source code only — lockfiles, generated files, and vendored or build directories are excluded.

My project grew. Will my bill jump immediately? No. An upward reclassification keeps your current rate for the rest of the cycle and the new rate starts next cycle, flagged in advance. A project that shrinks gets the cheaper rate right away.

Do micro projects count less toward my DriftScore too? No. Billing weight is not risk weight. Every project — micro, small, or standard — is fully included in DriftScores and the portfolio view.

How is the billable number rounded? Always down. 1.9 billable raw is billed as 1.

Related Commands

Vibgrate CLI

See a real scan run

A replay of the actual CLI running against our test repositories — live progress, real findings, a genuine DriftScore. Nothing executes in your browser.

Replay
demo@vibgrate — bash
npx @vibgrate/cli scan
 
╭──────────────────────────────────────────╮
Vibgrate Drift Report
╰──────────────────────────────────────────╯
 
── node-turborepo (node) .
Runtime: >=18.0.0 (6 majors behind)
Frameworks:
Turbo: 1.13.4 → 2.10.12 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
1 current 1 1-behind 3 2+ behind 1 unknown
 
── @repo/admin (node) apps/admin
Frameworks:
TanStack Query: 5.102.5 → 5.102.5 (current)
React: 18.3.1 → 19.2.8 (1 behind)
React DOM: 18.3.1 → 19.2.8 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Vite: 5.4.21 → 8.2.2 (3 behind)
Dependencies:
3 current 9 1-behind 3 2+ behind 4 unknown
 
── @repo/api (node) apps/api
Frameworks:
Express: 4.22.2 → 5.2.1 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Vitest: 1.6.1 → 4.1.11 (3 behind)
Dependencies:
7 current 5 1-behind 3 2+ behind 4 unknown
 
── @repo/web (node) apps/web
Frameworks:
Next.js: 14.2.35 → 16.3.3 (2 behind)
React: 18.3.1 → 19.2.8 (1 behind)
React DOM: 18.3.1 → 19.2.8 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
2 current 6 1-behind 3 2+ behind 5 unknown
 
── @repo/config (node) packages/config
Frameworks:
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
2 current 2 1-behind 5 2+ behind 0 unknown
 
── @repo/database (node) packages/database
Frameworks:
Prisma: 5.22.0 → 7.10.0 (2 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
1 current 0 1-behind 3 2+ behind 1 unknown
 
── @repo/types (node) packages/types
Frameworks:
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
0 current 0 1-behind 1 2+ behind 1 unknown
 
── @repo/ui (node) packages/ui
Frameworks:
React: 18.3.1 → 19.2.8 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
React: 18.3.1 → 19.2.8 (1 behind)
Dependencies:
1 current 4 1-behind 1 2+ behind 1 unknown
 
── @repo/utils (node) packages/utils
Frameworks:
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Vitest: 1.6.1 → 4.1.11 (3 behind)
Dependencies:
0 current 1 1-behind 2 2+ behind 1 unknown
 
Tech Stack
Frontend: React, React DOM
Meta-frameworks: Next.js
Bundlers: tsx, Turbo, Vite
CSS / UI: Autoprefixer, PostCSS, Tailwind CSS
Backend: Express
ORM / Database: Prisma, Prisma Client
Testing: Vitest
Lint & Format: ESLint, ESLint Prettier, ESLint React, Prettier, typescript-eslint
 
Services & Integrations
Auth: JWT 9.0.3
Databases: Prisma 5.22.0
 
TypeScript
v5.3.3 · strict ✔ · MIXED · target: ES2022
 
Build & Deploy
Package Managers: pnpm
Monorepo: npm-workspaces, pnpm-workspaces, turbo
 
Product Purpose Signals
Frameworks: react, nextjs
Evidence: 177
Top Signals:
- [heading] Dashboard (apps/admin/src/pages/Dashboard.tsx)
- [title] Revenue Overview (apps/admin/src/pages/Dashboard.tsx)
- [copy] workspace:* (packages/ui/package.json)
- [copy] ./dist (packages/ui/tsconfig.json)
- [copy] ./src/index.ts (packages/ui/package.json)
- [copy] @repo/config/tsconfig-base.json (packages/ui/tsconfig.json)
- [copy] @repo/ui (packages/ui/package.json)
- [copy] #3b82f6 (apps/admin/src/pages/Dashboard.tsx)
Unknowns:
- No pricing or billing evidence found.
- No integrations/connectors evidence found.
- No route structure evidence found.
 
Security Posture
Lockfile ✖ · .env ✔ · node_modules ✔
 
Platform
Native modules: turbo
 
Code Quality
Files: 36 · Functions: 183 · Avg complexity: 2.62 · Avg length: 21.13 lines
Max nesting: 2 · Circular deps: 0 · Dead code: 0%
God files: apps/admin/src/pages/Products (448 lines)
 
Database Schema
postgresql · 8 models · 1 enum
Models: Address, CartItem, Category, Order, OrderItem (+3 more)
 
Findings (16 errors, 11 warnings)
Node.js runtime ">=18.0.0" reached end-of-life on 2025-04-30 (latest: 24.0.0).
vibgrate/runtime-eol in .
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in .
60% of dependencies are 2+ major versions behind in node-turborepo.
vibgrate/dependency-rot in .
@types/node is 6 major versions behind (spec: ^20.11.0, latest: 26.3.0).
vibgrate/dependency-major-lag in .
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in apps/admin
Vite is 3 major versions behind (current: 5.4.21, latest: 8.2.2).
vibgrate/framework-major-lag in apps/admin
vite is 3 major versions behind (spec: ^5.0.12, latest: 8.2.2).
vibgrate/dependency-major-lag in apps/admin
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in apps/api
Vitest is 3 major versions behind (current: 1.6.1, latest: 4.1.11).
vibgrate/framework-major-lag in apps/api
@types/node is 6 major versions behind (spec: ^20.11.0, latest: 26.3.0).
vibgrate/dependency-major-lag in apps/api
vitest is 3 major versions behind (spec: ^1.2.1, latest: 4.1.11).
vibgrate/dependency-major-lag in apps/api
Next.js is 2 major versions behind (current: 14.2.35, latest: 16.3.3).
vibgrate/framework-major-lag in apps/web
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in apps/web
@types/node is 6 major versions behind (spec: ^20.11.0, latest: 26.3.0).
vibgrate/dependency-major-lag in apps/web
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/config
56% of dependencies are 2+ major versions behind in @repo/config.
vibgrate/dependency-rot in packages/config
eslint-plugin-react-hooks is 3 major versions behind (spec: ^4.6.0, latest: 7.1.1).
vibgrate/dependency-major-lag in packages/config
Prisma is 2 major versions behind (current: 5.22.0, latest: 7.10.0).
vibgrate/framework-major-lag in packages/database
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/database
75% of dependencies are 2+ major versions behind in @repo/database.
vibgrate/dependency-rot in packages/database
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/types
100% of dependencies are 2+ major versions behind in @repo/types.
vibgrate/dependency-rot in packages/types
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/ui
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/utils
Vitest is 3 major versions behind (current: 1.6.1, latest: 4.1.11).
vibgrate/framework-major-lag in packages/utils
67% of dependencies are 2+ major versions behind in @repo/utils.
vibgrate/dependency-rot in packages/utils
vitest is 3 major versions behind (spec: ^1.2.1, latest: 4.1.11).
vibgrate/dependency-major-lag in packages/utils
 
╭──────────────────────────────────────────╮
Top Priority Actions
╰──────────────────────────────────────────╯
 
1. Upgrade EOL runtime in node-turborepo
End-of-life runtimes no longer receive security patches and block ecosystem upgrades.
./.
>=18.0.0 → 24.0.0 (6 majors behind)
Impact: −10 drift points (runtime & EOL)
 
2. Fix security posture: no lockfile found
Without a lockfile, installs are non-deterministic. Run the install command to generate one and commit it.
./
Missing: package-lock.json, pnpm-lock.yaml, or yarn.lock
 
3. Upgrade Vite 5.4.21 → 8.2.2 in @repo/admin (+2 more)
3 major versions behind. Major framework drift increases breaking change risk and blocks access to security fixes and performance improvements.
./apps/admin
Vite: 5.4.21 → 8.2.2 (3 majors behind)
./apps/api
Vitest: 1.6.1 → 4.1.11 (3 majors behind)
./packages/utils
Vitest: 1.6.1 → 4.1.11 (3 majors behind)
Impact: −5–15 drift points
 
4. Reduce dependency rot in @repo/types (100% severely outdated)
1 of 1 dependencies are 2+ majors behind. Run `npm outdated` and prioritise packages with known CVEs or breaking API changes.
./packages/types
typescript: 5.9.3 → 7.0.2 (2 majors behind)
Impact: −5–10 drift points
 
5. Reduce dependency rot in @repo/database (75% severely outdated)
3 of 4 dependencies are 2+ majors behind. Run `npm outdated` and prioritise packages with known CVEs or breaking API changes.
./packages/database
@prisma/client: 5.22.0 → 7.10.0 (2 majors behind)
prisma: 5.22.0 → 7.10.0 (2 majors behind)
typescript: 5.9.3 → 7.0.2 (2 majors behind)
Impact: −5–10 drift points
 
╭──────────────────────────────────────────╮
Architecture Layers
╰──────────────────────────────────────────╯
 
Archetype: nextjs (80% confidence)
Files classified: 24 (11 unclassified)
Folders classified: 8
apps/admin/src presentation 100% 4 files
apps/admin/src/pages presentation 100% 2 files
apps/api/src/middleware middleware 100% 2 files
apps/api/src/routes routing 100% 2 files
apps/web/src/app presentation 100% 4 files
apps/web/src/app/products presentation 100% 2 files
apps/web/src/app/products/[id] presentation 100% 1 file
packages/ui/src presentation 100% 6 files
Unclassified source (sample): 11
 
presentation 15 files drift ████████████████████ 100 risk high
routing 4 files drift ████████████████████ 100 risk high
middleware 2 files drift ███████▍░░░░░░░░░░░░ 37 risk moderate
config 2 files drift ░░░░░░░░░░░░░░░░░░░░ 0 risk none
shared 1 file drift ████████████████████ 100 risk high
 
╭──────────────────────────────────────────╮
DriftScore Summary
╰──────────────────────────────────────────╯
 
DriftScore: 66/100
Risk Level: HIGH
Projects: 9
Classified: 8 nano · 1 micro · 0 small · 0 standard
Billable: 0.42 · 9 detected → 0.42 billable projects (micro-project pricing)
0.1 micro · 0.32 nano
These fractions add up across repositories, then round down to whole billable projects.
 
Score Breakdown
Runtime: ████████████████████ 100
Frameworks: █████████▏░░░░░░░░░░ 46
Dependencies: ██████▏░░░░░░░░░░░░░ 31
EOL Risk: ████████████████████ 100
 
Scanned at 2026-08-26T09:08:28.481Z · 7.1s · 286 files scanned · 56 workspace files · 27 dirs
Press Run to start.