Editor's note: By Omar Bohsali, Staff Software Engineer, LendingHome, Sam Aarons, Senior Software Engineer, LendingHome, and Dimitri Dadiomov, General Manager, Retail Investing, LendingHome
LendingHome is an online marketplace lender founded with the vision of being the best way to get a mortgage. For borrowers, this means the best way to apply for a mortgage with the most competitive rates. For investors, this means the best way to invest in mortgages as an asset class.
Since its founding in 2013, LendingHome has grown quickly and originated over $750m in loans to date. Most of these are short-term bridge loans that have a 12-month term, and are often used by buyers to purchase and renovate properties. For a case study of how this works in practice, check out this story about a fix and flip in Oakland.
LendingHome’s business is a two-sided marketplace that connects two types of customers: borrowers and investors. LendingHome offers an easy online flow for borrowers to apply for and get a mortgage. The mortgage application feeds into our origination system, which handles property valuation, underwriting the borrower, and simplifies the hundreds of steps required to vet and approve a mortgage. Finally, once the the loan is approved and funded, investors invest in those loans and grow their portfolios over time.
Building and scaling this product is a balance between keeping up-to-date with innovative technologies and knowing when to rely on seasoned, battle-tested tools that have powered successful companies in the past. We think about this decision a lot and approach it very deliberately.
As our business grows and evolves, so does our technology stack. Here’s a snapshot of the stack that has taken us to be the leader in real estate marketplace lending over the past three years.
LendingHome’s platform product does not do as many page views or as much throughput as a pure consumer product, but in our business, one user finishing a marketing flow could mean thousands of dollars in revenue. So our system must be rock-solid reliable, but at the same time very fast; a few hundred milliseconds in page load time might cost us the entire sale.
Additionally, we’re also operating a financial services business, so it’s important to move faster than our competitors, but at the same time, be thoughtful and make sure we maintain simplicity and security at our core. Otherwise, the system can get very complex very quickly.
Generally the product is split into four major applications:
- Consumer: A end-user facing application handling both the loan application process for the borrower as well as various investment management services for the investor.
- Operations (ops): An internal application designed for our in-house loan specialists to handle every step of the loan from application to underwriting to servicing to final payoff.
- Money movements: An internal application which integrates with our bank partners and exposes a simple API for sending ACH and federal wires.
- Salesforce Integration: We’re a two-sided marketplace, and we keep track of both borrower and investor relationships using Salesforce.
LendingHome has been a Heroku customer from the very beginning. Heroku enables us to very easily deploy and scale both our application layer as well as our database and caching layers. It also takes away the routine server management, which frees up our devops team and lets them focus on developer tools and more bespoke services that we need to host on Amazon Web Services. We periodically discuss whether it make sense to switch off of Heroku, and while it may happen in the future, we’re not there yet.
Our frontend started off as “vanilla” server-side HTML rendered through Ruby on Rails using HAML and jQuery. This was a great start for us, and it really enabled us to get going quickly from the early days.
This was a great process - when we were laying the foundation on our retail investing site, we spent a few days rewriting the demo in React instead of plain Rails just to see what the tradeoffs would be. We ended up loving the rewrite so much we decided then and there to slowly migrate other new projects over to the new method.
The limiting factor to switching the whole site over to React/ES6 is familiarity and time. It’s hard to rewrite an entire front-end in a new framework; it’s even more complicated when it’s a brand new framework that few are familiar with. Naturally, we have some engineers who lean towards the front-end side of things, so we do weekly sessions over lunch where someone presents about React and general client frontend infrastructure; these meetings are really valuable and are a great way for our team to keep up-to-date with what’s taking place on the frontend.
Finally, not everything needs to leverage React’s dynamic UI capabilities, so we still sometimes create one-off rails views for simple use cases. We try to adopt new technologies, but at the same time, avoid being dogmatic, and instead focus on using the right tool for the job.
With our frontend turning into more of a single page app, we’re constantly simplifying our backend, removing server-side rendering, and turning things into simple endpoints as much as possible. Pages that were previously complex views with a lot of server-side logic become endpoints, cleanly separating the business from the display logic. We use PostgreSQL as our primary database. Also, we use over 100 different rubygems as part of our backend alone.
Once we originate a loan, servicing is the process of making sure that payments are made on time and that investors get their money back (plus interest); we’ve built out an end-to-end servicing engine that handles every detail of this transaction. It handles everything from, reading payment activity from subservicers, collecting payments from borrowers, calculating payment waterfalls for investors, dealing with complex interest calculations, to much much more.
A mortgage is a long-term conversation between a borrower and an underwriter/servicer (us); as such, reliable communication in both directions is very important. We communicate with our borrowers in many ways; the main ways are via phone (SMS and voice) via Twilio, and by email (via Mailgun). They’re both the industry leaders and the standard, and we’ve worked with them from the very beginning.
Our retail investors buy fractional notes in the loans we originate, so instead of buying the entirety of a $150,000 loan, they can buy a smaller piece and distribute their investment capital across many loans. Many investors initially pick-and-choose the investments themselves; with time, many of them use our Automated Investing system to automatically buy parts of loans as soon as they become available. Investors can choose from one of three different investment programs, and AutoInvest handles the rest.
Document Generation & Parsing
A standard mortgage contract might have upwards of 1,000 pages of contract terms and signatures; as such, we’ve built out an extensive document generation and parsing framework; the main components are DocGen, CloudConvert, RightSignature, and wkhtmltopdf.
DocGen and CloudConvert generate PDF documents used everywhere in our company; they generate closing packets, handle contracts, and eventually generate the entire loan package. wkhtmltopdf generates regular reports (such as monthly statements); we specifically use the Heroku variant over the base because it abstracts away the dependency management and keeps track of the wkhtmtopdf binary for us.
DocViewer is our custom-built document processing pipeline. Almost every document goes through it upon upload; key facts are automatically extracted and parsed. Architecturally, we built DocViewer atop AWS Lambda; documents go through pipeline as soon as they’re uploaded and then saved on S3. Before we use the data that comes from DocViewer, it’s first verified by a human so we can make sure it’s correct.
This loop is fortuitous in at least two ways. First, it reduces our staff’s workload by automatically parsing data and drives down our loan processing time. While banks take months on end to close a loan, our goal is to do it in a fraction of that time without compromising on quality. Second, we use the corrected values input by our staff as a huge supervised training dataset, resulting in a feedback loop where merely using DocViewer makes it better.
Continuous Integration & Testing
We’re very diligent about testing; our test suite consists of over 30,000 tests that run hundreds of times a day. We’ve gotten a very positive ROI from investing time to make this process better - reducing a full spec suite run by just 5 minutes means hours of engineering time saved every day. We use RSpec for core testing, and Capybara/Poltergeist for headless integration tests.
For the past year, we had been running all of our specs using RSpec on CircleCI but recently made the switch to BuildKite because it allows much better granularity into figuring out where tests are failing. It has an amazing feature that lets you re-run a specific container’s tests, so if you have a false negative (we call these ‘blinky’ specs), you can re-run specifically that container and get a green build much faster than having to kick off the entire test suite from scratch. This functionality, combined with much greater stability and configuration options, was enough for us to move from CircleCI to BuildKite. Long gone are the days of waiting for test environments to free up.
We also have a bot in Slack that pings us when builds go red or green; this lets developers go off and work on other things while the spec suite is running. This is another one of those things that is a very simple piece of technology, but practically, it frees up developers to do something else and get asynchronously notified when a build finishes.
We also use Hound and ESLint (using the AirBnB style guide) to lint our JS, CSS, and Ruby code. These tools run on every build so that we can maintain a consistent style. Often times, there are many ways of doing something, but it’s important to have consistency on an ever-increasing codebase.
From very early on, we knew that third party vendor integrations were a key piece to our platform, so we invested a lot of upfront engineering time to build a framework that could handle almost any fathomable vendor integration while being cognizant of key constructs like rate limiting, protecting personally identifiable information (PII), managing access, and credential security. Today, we have over fifty vendor integrations that do everything from pulling property data, finding home price trends, checking borrower creditworthiness, verifying investor status, and much, much more. Here are a few of those integrations.
When lending money, we have to be very sensitive about whom we’re lending money to or who we’re accepting investment from. Lending money to someone who is not trustworthy is a huge business loss for us and our investors; lending money to someone who is on an OFAC (Office of Foreign Assets Control) list is an offense with huge penalties. That’s where BlockScore comes in. We use it to check OFAC lists to make sure that investors / borrowers are not on any prohibited individuals lists. This is an amazing service. The alternative would be managing lists ourselves; it’s great that someone fills this need.
Lob helps us verify mailing addresses. There are many ways of representing a street address, and the USPS comes with its own idiosyncrasies as well. Sometimes, users will provide their street address but not apartment number; some will spell a street name incorrectly; address parsing is actually much more complicated than it sounds. Lob is helpful because it quickly notifies the user if there’s a problem and helps them input the right address.
We use InvestReady (formerly known as Accredify) to verify investor accreditation. Because of the regulatory regime under which LendingHome’s investor notes are currently offered, we have to check that our investors are accredited investors. Instead of doing this ourselves, we partnered with InvestReady, who handles checking accreditation and reaccreditation for us and provides us with accreditation periods for each investor via an API.
Some other noteworthy integrations include RedBell, LPS, ClearCapital, Zillow, Walkscore, Trulia, RentRange, and CredCo.
Data and Analytics
Mortgage is a hugely data-driven business; as such, we’re very heavy users of Amazon Redshift in addition to our platform database (Postgres). We were actually one of the first users of Redshift in 2013, and use it extensively to model credit default probabilities and stress test various macroeconomic scenarios to better mitigate risk.
We also use Looker extensively. Initially we used it as a front-end to our Amazon Redshift cluster; as our organization grew, we integrated it with almost all of our company’s data sources. Now, it’s ubiquitous at LendingHome and it’s used for everything: some use it query databases, some for risk and credit modeling, and others for complex business dashboards and reporting. It’s extremely difficult to build a data analytics tool that serves all of these purposes so well, so we’re very happy with Looker and how it is a source of truth for many big decisions and ultimately helps us stay a data-driven organization.
For monitoring website traffic, we use Google Analytics for general web traffic, Mixpanel for funnel analysis and user retention tracking and Segment to help us manage our other front end integrations. Keeping track of everything that happens helps us remain a data-driven company.
Source Code Management
Our code has lived in GitHub from day one (the first commit message was aptly titled “Initial commit”) and over 75,000 commits later, we’re still using it happily. We previously branched feature branches off of master; last year this got unwieldy so we adopted the git-flow model, which has helped us keep the codebase clean and ready to deploy when needed.
Monitoring & Error Reporting
We’re also huge fans of Sentry for error reporting. We built a tool that knows where to route error messages so that whenever something goes wrong, the right team’s slack channel gets notified. Initially, we pushed all of our error messages into a slack channel called #errors, which started getting a little bit overwhelming, so we developed the Sentry router which forwards exceptions based on regular expressions.
FullStory has been one of our best investments to-date. Since we’re doing most things in React/Redux, it’s very easy to see exactly what a user is doing and how they are behaving when using any part of our application. This is great because we can understand what a user is doing, and very rapidly reproduce any issues. While the subscription is a little bit on the pricey side ($399/month), it’s saved us so much engineering time that it has more than paid for itself every month.
Pingdom is our primary fault monitoring and uptime reporting and we have it connected via SMS as well as Slack alerts.
We think a lot about tracking performance. As said above, page speed really matters. Page timeouts can equate to hundreds of thousands of dollars in lost origination revenue. With performance and monitoring as a top priority, we turned to New Relic to profile our requests and help us understand what was causing latency.
We recently switched to doing work in bi-weekly sprints and use JIRA for issue tracking. Before that, we tracked everything on Pivotal Tracker; before that we were on Google Spreadsheets; and before that, we had a shared Google doc where we kept the product roadmap. These types of issue tracking tools are like gym memberships: they’re only useful if you use them consistently, so we’ve been mindful to not switch to a tool that is too big too quickly. We’re still unlocking new features that increase our productivity in JIRA, and it’s our needs that dictate what features we use, and not the other way around.
Almost all engineering team communication happens on Slack. We started off with one main engineering channel, but we’ve recently started creating side rooms for different teams to keep the communication overload manageable. We still discuss general engineering topics in the engineering room.
We use Google Apps extensively: calendaring, email, spreadsheets, and docs. We’re starting to use Dropbox Paper more for document collaboration and brainstorming, just because it’s an easier experience when many people are simultaneously collaborating.
CRM and Marketing
Our sales team keeps track of clients (and potential clients) using Salesforce, so we’ve built out a couple of integrations that push data from our platform into it. It can be a little bit arduous at points, but Salesforce is the lingua franca of the sales world, and while developing sync features takes up a lot of time, it’s an important enabler for our revenue. We also use Marketo for lead scoring and marketing.
Before we build any user-facing features, we do mockups in Sketch and Invision, which helps us iterate rapidly and saves us time. Instead of building out a feature and then realizing that something needs to be changed, we’ll do mockups in sketch, discuss them, do more mockups, and then once we’re ready, actually implement them. We still have moments where we have to go back and make changes to features once we’ve built them, but using Sketch and Invision really reduces the amount of time spent re-building things and all-in-all makes us a lot more productive.
Work in Progress
As our company grows and business needs evolve, so does our product and tech stack. We’re constantly building new features, adding new integrations, and removing old ones. For more information check out the borrower experience at lendinghome.com and the investor experience at lendinghome.com/invest. While we’ve accomplished a lot, we’re still only getting started in the trillion dollar mortgage industry!
Our engineering team is also growing. We're hiring engineers in our offices in San Francisco, CA and in Columbus, OH. See our careers page to learn more. We look forward to hearing from you!