TL;DR: You can think of Ethereum as a "heavy" blockchain that does everything for you. All the complexity is handled there, computations run there, and all scalability and security issues need to be handled at the blockchain layer. Blockstack puts minimal logic into a blockchain and handles scalability outside of the blockchain by re-using existing internet infrastructure in new ways.
Thanks for the question and a warm welcome to anyone developing on Ethereum. Blockstack and Ethereum belong in two different schools of thought when it comes to using a blockchain and building decentralized apps.
Let me expand a bit on Jude's post.
Complexity in the blockchain vs. outside of the blockchain:
Ethereum puts all the complexity (computations and storage) into the blockchain itself. Blockstack wants to use blockchains (any underlying blockchain really) as a layer of trust used for bootstrapping other components on top. Meaning that Blockstack wants to put as little logic and data in a blockchain as possible.
Scalability of data storage
Blockstack has the philosophy that existing internet infrastructure should be re-used for performance and scalability. Blockstack enables users to use arbitrary storage backends like Dropbox, Amazon, Google as "dumb drives". Only pointers to the storage backends are stored with Blockstack and encrypted/signed data is kept at storage providers. Blockstack can give you 98% performance of using a service like Amazon S3 directly and can scale out to comparable levels of existing apps running on the traditional internet and datacenters.
By contrast, Ethereum is focused on (1) storing data in a global Patricia tree within the blockchain, and (2) trying to build decentralized off-chain storage systems like Swarm. When these decentralized storage systems become available for general use, they can be used with Blockstack by writing "drivers" for them.
Introducing new features to the system
Ethereum is a blockchain, whereas Blockstack is a "layer 2" system (i.e. Blockstack is agnostic to the underlying blockchain, and is designed to run on top of existing ones). If you want to make changes to Ethereum, you'll need to get buy-in from miners and other parties in order to deploy them. If you want to make changes to Blockstack, you can do so independently of the blockchain.
Mitigation against blockchain failures
Blockstack currently runs on top of the Bitcoin blockchain. The project is currently evaluating/discussing support for other blockchains. In the event of a blockchain failure (e.g. 51% attack, netsplit, hard-fork), the system/network can migrate to another blockchain transparently. Blockstack has done one such successful migration in the past (Namecoin to Bitcoin), since it was discovered that a single miner had more than 65% hashing power on the underlying blockchain. To the best of our knowledge, this was the first time a production blockchain application outlived the underlying blockchain. This design principle decouples the risk of a failure at the blockchain-level from the success of apps and services built on top.
Scalability of computations sent to the network:
Jude mentioned on-chain and offchain computations above. At a high level, Ethereum gives you a Turing-complete language at the blockchain-level, and all nodes need to process computations to catch up to the latest state/block. Blockstack gives you the ability to write Turing-complete state machines at "Layer 2", called virtualchain in Blockstack. Your node can choose to process computations for only the state machines that you're interested in. Instead of processing all transactions/computations from all the nodes, you only process the stuff you're interested in while remaining on the same global network. This would help you avoid scaling issues.
For more information, see the Blockstack paper published at USENIX'16 and the Virtualchain paper published at DCCL'16.