If you manage anywhere from a couple dozen to a few hundred units, you've probably already priced out AppFolio or Buildium. And you've probably balked -- not because the software is bad, but because most of what it does, you don't need yet. Full property management platforms bundle in a rent ledger with ACH payment processing, tenant screening and background checks, lease e-signing, and portfolio-wide financial reporting. Those are real, valuable features. They're also per-unit monthly fees and weeks of setup for problems you may not have. Your rent probably already comes in through Zelle, a bank's bill-pay, or checks, and your leases get signed on paper or DocuSign just fine. The actual daily pain point is narrower and dumber than any of that: a tenant texts you a blurry photo of a leaking faucet at 9pm, it gets buried under three other conversations, you forget which plumber you already called, and three weeks later you have no idea if it ever got fixed. That's a tracking problem, not an accounting problem. You can build the fix yourself in an afternoon.
Start with the foundation everything else links to. Fields: Property Address, Unit Number, Property Manager Assigned (if you have more than one PM covering different buildings), Number of Bedrooms/Bathrooms (useful context for vendors), and Notes. Even if you're a one-person operation today, build this as if you'll add a second property manager later -- it costs nothing now and saves a painful re-structure later. This table is the anchor for every other table in the system, so get the unit-level granularity right from day one: a request tied to '123 Main St' isn't useful if that building has 12 units and you don't know which one has the broken dishwasher.

Fields: Name, Phone, Email, Unit (linked record), Lease Start Date, Lease End Date, Emergency Contact. Link each tenant to exactly one Unit record. This matters more than it sounds like it should: in a multi-tenant building, you need to know not just which apartment has an issue, but which specific person reported it and how to reach them back. It also means when a lease ends and a new tenant moves in, you're not editing old records -- you're adding a new linked tenant to the same unit, and your historical maintenance record for that unit stays intact and correctly attributed.
This is the core of the tracker. Fields: Unit (linked), Tenant (linked), Category (Plumbing, Electrical, Appliance, HVAC, Other), Description, Photo Upload, Priority (Low, Medium, High, Emergency), Status, Vendor Assigned (linked, once you add Step 5), Date Submitted, Date Resolved. Link to both Unit and Tenant, not just one or the other. If you only link to Unit, you lose accountability -- who actually reported this, and can you reach them to confirm access for the vendor? If you only link to Tenant, you lose the physical context once that tenant moves out, and you can't pull a maintenance history for a specific unit across multiple tenants over the years (which you'll want when you're deciding whether that unit's HVAC needs replacing rather than another patch job). Make Status a real pipeline, not a free-text field: Submitted -> Acknowledged -> Vendor Assigned -> In Progress -> Resolved. That progression is what lets you glance at a dashboard and know exactly where every open ticket stands without calling anyone. And don't skip Photo Upload -- a photo of the leaking pipe or the tripped breaker means your vendor can often diagnose the problem, bring the right part, and quote a fair price before they even step on-site. That alone cuts down a huge amount of the back-and-forth phone tag that eats your afternoon.
We built the tracker described in this guide, not just described it -- a real, working app with sample data, live right now. The [Maintenance Requests board](https://helpdesk-ps-preview-fadb933e.apps.sideblend.com/tickets) is the piece worth clicking through first: it's the Kanban pipeline from Step 3 above, columns for Submitted, Acknowledged, Vendor Assigned, In Progress, and Resolved, with real sample requests (a leaking faucet, a tripped breaker, an AC unit blowing warm air) moving through them. From there the sidebar links to [Units](https://helpdesk-ps-preview-fadb933e.apps.sideblend.com/units) and [Vendors](https://helpdesk-ps-preview-fadb933e.apps.sideblend.com/vendors) so you can see how the linked tables from Steps 1 and 5 actually look once they're populated. This is a sandbox demo, not a template you install -- it exists so you can see the shape of the finished thing before you build your own.

This is the piece that actually gets you out of text messages. Build a simple public form -- no login required -- that writes directly into the Maintenance Requests table: tenant picks their unit from a dropdown (or it's pre-filled if you send them a unit-specific link), selects a category, writes a description, uploads a photo, and submits. You put the link on a laminated card in the unit, in your welcome packet, or texted once to every tenant. The moment this exists, tenants stop needing to call you to report something, and -- just as important -- stop needing to call you to ask for an update. If you add a lightweight status lookup (tenant enters their unit/email, sees where their ticket sits in the pipeline), you eliminate the single most common reason tenants call a property manager: 'hey, did you ever get someone out here?' This same pattern -- a no-login public form that writes into a structured pipeline -- is the same approach we've covered for building a multi-step client intake form that feeds a CRM, just applied to a different kind of intake.
Fields: Vendor Name, Trade/Specialty (plumber, electrician, HVAC, handyman, appliance repair), Phone, Email, Notes (rates, reliability, insurance on file). Link this table to Maintenance Requests through the Vendor Assigned field. Once this link exists, two things become trivial that used to require memory or a separate notebook: you can see at a glance which vendor is on the hook for which open ticket across your entire portfolio, and every resolved request becomes a permanent record of who did the work, when, and on what issue. That record matters more than it seems -- when a tenant disputes whether something was ever fixed, or when you're deciding whether to keep using a vendor who's slow to close tickets, you have an actual paper trail instead of a guess.

Once the pipeline is running and requests are actually flowing through it, layer on a simple dashboard: open requests grouped by property, and a second view grouped by status, so you can spot bottlenecks (too many stuck at 'vendor assigned' means your vendor relationships need attention, not your tenants). Pair that with an automatic notification -- email or SMS -- to the property manager the moment a new request comes in, so nothing sits unacknowledged in a queue nobody's watching. This is a light version of the kind of analytics and reporting you'd eventually want at real portfolio scale, and the notification logic is a straightforward workflow automation rule -- new record in Maintenance Requests, status equals Submitted, notify assigned PM.
Build 1 through 4 first. Properties, Tenants, Maintenance Requests, and the tenant-facing form together replace the spreadsheet-and-text-message chaos entirely -- that's the whole point, and it's usable the same day you build it. Add Vendors and the dashboard/notifications (5 and 6) once the core pipeline has been running for a week or two and you've got real requests flowing through it. There's no rush on those two; they're refinements, not requirements. Be honest with yourself about where this stops being enough. Once you're actually collecting rent through the platform, running background checks on prospective tenants, e-signing leases, and need audited financial reporting across a real portfolio, a full platform like AppFolio or Buildium starts earning its per-unit fee -- that's a different scale of problem than 'where did that plumber's number go.' This guide is deliberately scoped to the maintenance-tracking pain point on its own, because for most small-to-midsize operators, that's the actual daily fire, and it doesn't require a platform built for a REIT to put out. If you want a broader sense of when a narrower tool like this stops being enough and a heavier platform starts making sense, that's the same tradeoff we walk through in Buy vs. Build vs. ViibeStack.