Dear MarkedUp fans and users, I regret to inform you that MarkedUp will be closing its doors after more than two years of service. Our current plan is to shut everything down on November 30th, although that may be subject to change.

Long story short: our business struggled to find a viable business model with the amount of time we had on the clock. MarkedUp In-app Marketing was off to a very promising start, but unfortunately it takes a lot of capital and a lot of time to build up sales around a unique product – and we simply ran out of both.

For those of you who are worried about what happens when our service shuts down:

Most apps should not be affected by our service shutting down, even if you still have our SDK embedded inside your app. Our SDKs have been designed from day one to be resilient in the event that MarkedUp’s services experience a period of downtime. That being said, it’s in your best interests to migrate to Google Analytics, Flurry, or another analytics provider soon.

If you want backups of your data, please use the Excel® download links on your reports ASAP. Most reports should have these.

Any In-app Marketing customerswill not receive further invoices. We bill at the beginning of the month for MarkedUp IAM, and we will not be sending any further invoices.

Thanks for all of your support and feedback over the years. We worked hard to make sure we could provide you a responsive, easy-to-use and understand analytics experience and appreciate your patronage of our service.

On behalf of the MarkedUp family, thank you!

]]>http://blog.markedup.com/2014/11/markedup-is-shutting-down/feed/0Easy Mode: Synchronizing Multiple Processes with File Lockshttp://blog.markedup.com/2014/07/easy-mode-synchronizing-multiple-processes-with-file-locks/
http://blog.markedup.com/2014/07/easy-mode-synchronizing-multiple-processes-with-file-locks/#commentsTue, 29 Jul 2014 20:31:40 +0000https://blog.markedup.com/?p=6301Continued]]>Thanks to the introduction of new language features and frameworks such as C#’s async keyword more and more developers are learning how to use parallelism and multi-processing in production contexts. One of the consequences of this, however, is having to learn how to use synchronization mechanisms to serialize access to shared memory and other resources.

In mobile app development the entire conversation around synchronization is focused on synchronizing access to resources within the context of a single running application – because there are no major mobile app platforms that allow you to run multiple parallel instances of the same application.

In desktop app development, however, it’s totally common for end-users to be able to launch multiple instances of your application and therefore it becomes more important to understand how to synchronize access to shared resources across multiple distinct processes.

There are two common use cases for process synchronization:

The “single application instance” pattern – this means using a synchronization mechanism to prevent the user from launching more than one instance of your application. If you’re writing a Windows tray client that runs in the background and does file synchronization, remote backup, or anything else like that then you need to make sure that the user can’t accidentally kick off multiple instances of your backup software in parallel.

The “shared access to resource” pattern – suppose you have multiple processes that can all write some critical data to the user’s registry on Windows or perhaps an important settings file; you have to pick some method for synchronizing reads and writes to this data if your application can have multiple instances running in parallel.

In the case of the MarkedUp, we need interprocess synchronization between our customer’s apps for the following two cases:

Ensure that only one instance of a customer’s MarkedUp-enable desktop application can empty its “retry” queue – this is specific to a single customer’s application; if an end-user’s machine goes offline or if there’s an issue with our API, the MarkedUp SDK will save all of its undeliverable messages into a retry queue on-disk and retry sending them the next time the application runs OR if Internet connectivity is restored. If there are multiple processes running, we need to make sure that only one process can do this at a time.

Ensure that only one In-app Marketing message can be displayed to a customer at a time, across multiple MarkedUp-enabled applications from different software publishers – this is trickier, because we have to synchronize the In-app Marketing TrayClient across all MarkedUp-enabled applications running on a single user’s desktop.

Given these requirements, we decided that the safest approach to inter-process locking was to use an old-fashioned file lock!

How File Locks Work

The concept of a file lock is simple and it’s fairly ubiquitous in the real-world – anyone who’s done a lot of work with Ruby (Gemfile.lock) or Linux has used a file lock at some point in time.

A file lock is implemented by having multiple process look for a file with the same name at a well-known location on the file system – if the file exists, then each process knows that the lock has been held at some point in time. The lock is acquired when the file is written to disk and the lock is released when it is deleted.

Typically the lock file will contain some data about the ID of the process that last held the lock and the time when the process acquired it – that way processes can have “re-entrant locking” and lock timeouts, in the event that a process was forcibly killed before it had a chance to explicitly release the lock.

Here’s an illustrated example:

Process 1 acquires the lock by writing markedup.lock to the file system – and then it does its work against the shared resource. Process 2 attempted to acquire the lock but since the file is already in use, it has to wait until Process 1 releases the lock.

Process 1 releases the lock by deleting the markedup.lock file. Process 2 attempts to acquire the lock later and discovers that the markedup.lock file is missing, so it successfully acquires the lock by recreating the markedup.lock file and does its work against the shared resource.

File Locks in Practice (in .NET)

We picked a file lock over an OS-level mutex lock primarily because we couldn’t guarantee that the same thread that acquired a lock would be the same one that released it (required on Windows) – plus we wanted to have our own recovery mechanism to timeout locks.

]]>http://blog.markedup.com/2014/07/easy-mode-synchronizing-multiple-processes-with-file-locks/feed/0Real-time Marketing Automation with Distributed Actor Systems and Akka.NEThttp://blog.markedup.com/2014/07/real-time-marketing-automation-with-distributed-actor-systems-and-akka-net/
http://blog.markedup.com/2014/07/real-time-marketing-automation-with-distributed-actor-systems-and-akka-net/#commentsWed, 23 Jul 2014 23:17:37 +0000https://blog.markedup.com/?p=6241Continued]]>The MarkedUp team has had experience developing SDKs, high-performance APIs, working with Cassandra / Hadoop, and service-oriented software for several years. However, when we started laying out the blueprint for MarkedUp In-app Marketing we knew that it would require a radically different set of tools than the traditional stateless HTTP APIs we’d been used to developing for some time.

Some Background

Before we dive into the the guts of how the system works, it’s more important to understand what the MarkedUp team is trying to achieve and why.

Most marketing automation software is borderline terrible, ineffective, or totally onerous to use. This is largely because marketing automation is an afterthought and is hardly ever integrated into systems that software companies regularly use, such as product analytics.

We wanted to build a product that made it extremely easy to:

Quickly and successfully set up drip campaigns of messages, especially for users who are non-technical;

Sign up for MarkedUp In-app Marketing and define campaigns of messages that are delivered based on an end-user behavior;

MarkedUp In-app Marketing immediately begins filtering users based off of the behavior segments you defined and automatically subscribes them to any eligible campaigns.

And here’s an example of an actual behavior we can target:

“Select all users from the United States and Canada who installed after 6/1/2014, have run the app within the past two days, have had event foo, had event bar, and have viewed page “Buy.”

In this case events “foo” and “bar” are some arbitrary events that are specific to a MarkedUp customer’s application – they can mean anything.

Technical Challenges

So what’s challenging about building this product? Let’s put this in list form:

[Real-time] Customers get the best results on their messages when they’re delivered immediately after a user is “subscribed” to a campaign – therefore, our segmentation system for filtering subscribers must be capable of making decisions within seconds of receiving critical events. This eliminates traditional batch processing via Hive / Hadoop queries as a feasible option – we’re going to have to process data as streams instead.

[Stateful] Overwhelmingly, most campaigns customers define will require us to observe multiple events per user – this means that we have to maintain state that is incrementally completed for each user over multiple successive events. Given that this needs to be done in real-time we’re not going to read/write from a database on every request – state will probably have to be kept in-memory somewhere.

[Highly Available] The system must be capable of supporting millions of parallel data streams and must be able to recover from failures – we need to have a way of throwing hardware at the problem when demand on the system increases (happens suddenly when it does) and we need to be able to recover from software and hardware failures quickly.

[Remoting]The targeting system needs to be able to use the data-stream from our API in a loosely coupled fashion – we need some way of quickly sharing the fire hose of data that our API servers collect, and do it in a way that is loosely coupled enough where a downed in-app marketing server won’t disrupt the API from serving its primary function: storing customer’s data.

The real-time component is what makes this entire project a challenge – and no, it is not optional. It’s a real competitive advantage and essential to our “it just works” promise we make to our customers. We’re in the business of delivering on promise of “better experience than everything else” at MarkedUp.

So how in the hell were we going to be build a system that was highly-available, stateful, loosely-coupled, and able to respond in real-time?

Solution: Actor Model

As with 99% of challenging technical problems faced by today’s software developers, a solution was already invented in the early 1970s: the Actor model.

The Actor model’s premise is that every component of your system is an “actor” and all actors communicate with each other by passing immutable messages to each other. Each actor has a unique address inside an actor system, even across multiple physical computers, so it’s possible to route a message to one specific actor. Actors are also composed in hierarchies, and parent actors are responsible for supervising the child actors one level beneath them – if a child actor crashes suddenly the parent actor can make a decision about how to proceed next.

The actor model appealed to us for the following reasons:

Actors are cheap – you can have 10s of millions of them with minimal overhead. This means that we can have an actor to track every user / campaign tuple, of which there might be millions. This localizes the “filtering” problem nicely for us – we can define a filter that operates at the per-user level, so it’s a tiny piece of code. Sure, there might be millions of these filters running at once – but the code is highly atomized into small pieces.

Remoting and addressing between actor systems makes it easy to route data for each user to a specific location – using a technique like consistent hash routing, we can push all of the state for each individual user to the same location in memory even across a large cluster of machines and do it in a way that avoids load-balancing hotspots.

Actors only process one message in their inbox at a time – therefore it’s really easy to for us to process streams for individual users, since it will be done serially. This allows us to process data streams for each individual user and each in-app marketing campaign with a simple Finite State Machine.

Actor hierarchies and supervision allow our software to be self-healing and highly available – the supervision aspect of actor hierarchies is immensely powerful. It allows us to make local decisions about what to do in the event of failure, and we can simply “reboot” part of our actor system automatically if something goes wrong. In the event of hardware failure, we can re-route around an unavailable node and redistribute the work accordingly.

Actor model offers a fantastically simple API for highly concurrent computing, which is exactly what we need. We’re handling thousands of parallel events for hundreds of different apps running on millions of different devices – our incoming data stream is already inherently concurrent. Being able to manage this workload in a stateful way is challenging, but the Actor model exposes a simple API that eliminates the need for us to worry about threads, locks, and the usual synchronization concerns.

There are certainly other ways we could have solved this problem and we evaluated them, but we were ultimately sold on the Actor model because of its simplicity relative to the others.

Distributed Actor Systems in .NET with Akka.NET

Akka.NET offers all of the important features of the Actor model in C# and F#, and a number of critical features that were essential to building MarkedUp In-app Marketing:

A hefty collection of built-in router actors, such as the RoundRobinRouter and the ConsistentHashRouter – both of which include the ability to automatically scale up or down on-demand if needed (via the Resizer function.)

And some pretty insane performance benchmarks (21 million messages per second) – bottom line is that the overhead of the Actor system itself probably isn’t going to be an issue for us.

We settled on Akka.NET as our framework and used it as the building blocks for the back-end of MarkedUp In-app Marketing.

We’ve left out some details of our service-oriented architecture above, but the network topology shown above covers the In-app Marketing product in its entirety.

MarkedUp has two public services exposed directly to end-users via an HTTP API:

The “MarkedUp API” – which is what our analytics SDKs communicate with inside your applications; it handles millions of HTTP requests per day and does 100m+ database writes per day. Most of those writes are counter updates which are inexpensive, but the bottom line is that there’s a lot of activity going on inside this API.

The Win32 Mailbox Service – a brand new service that we released as part of our In-app Marketing launch for Windows Desktop applications; all of our Win32 messaging clients work via HTTP polling since there’s a number of tricky permissions issues related to keeping an open socket in the background on each version of Windows (a subject for a separate blog-post.) This is the endpoint these clients use to check for available messages.

The goal of our Targeting System is to take the streams of data directly from the MarkedUp API servers and populate mailbox messages for individual users in accordance with the app developer’s filtering rules, and we use Akka.NET to do this.

Filtering Messages, Users, and Campaigns with Actors, State Machines, and Routing

Success for MarkedUp In-app Marketing’s Targeting System is defined as “being able to subscribe a user into one or more campaigns within seconds of receiving the segmentation data specified by the customer” for N concurrent users per server, where N is a coefficient determined largely by the size of the hardware and number of potential campaigns per-user, which varies for each one of our customer’s apps.

Our product is designed to filter messages for specific users for campaigns that are specific a customer’s app, so we reflected these relationships in our actor hierarchy.

Data arrives to the Targeting System from the MarkedUp API via Akka.NET’s built-in remoting over TCP sockets, and we’ll get into the details in a moment. For the time being, all you need to know is that the data is routed to our API Router, a round-robin pool router actor that specializes in concurrently load-balancing requests across a number of worker actors (API Router Agents) who actually respond to the requests.

The number of workers that exist at any given time can be hard-coded to a value of N workers, or it can be resizable based on load depending on how you configure the router.

Each API Router Agent is responsible for doing one thing: making sure that data for a specific user makes it to that user’s actor. Here’s what that process looks like:

The PatternMatch.Match method is used to filter messages based off of their C# type – any messages that we don’t match are “unhandled” and logged. In Akka.NET, all messages are just objects.

In terms of where we’re sending messages, we have a fixed address scheme inside our in-app marketing product that makes it easy for us to locate individual users, campaigns, and apps. Suppose we have an app called “App1” and a user called “UserA” – we use Akka.NET’s built-in address scheme to make it really easy to determine if this user already exists.

Every single actor inside Akka.NET has a unique address – expressed via an ActorUri and ActorPath, like this:

When you’re routing messages within the in-process actor system all you really care about is the ActorPath – the /user/parent/child part.

We constructed our actor hierarchy to include a single “App Master” actor (/user/apps), responsible for supervising every “App Actor” for our customer’s apps (/user/apps/{customer’s app ID}) – and every single user we ever observe inside MarkedUp is always associated with an app, so every App Actor supervises one or more “User Actors” who can be found at /user/apps/{customer’s app ID}/{userId}.

If App Master shuts down or restarts, all of its child actors shutdown or restart with it – if a child actor dies on its own, it’s up to the App Master to decide what to do next. This is the essence of how actor supervision works.

So the API Router Agent forwards the message to App Master which kicks off a process of lazily creating App and User actors on-demand, but eventually the messages do arrive inside the inbox of the User Actor.

The User Actor implements an Akka.NET Finite State Machine to determine which campaigns this user should start filtering for – this is determined by (1) which, if any, campaigns are available for this app and (2) which campaigns this user has already been subscribed.

After a User Actor has determined that it’s eligible to be subscribed into at least 1 additional campaign, it’ll change it’s state into a “Ready” state where it begins sending messages to the “Campaign State Actors” responsible for filtering the rules for every possible campaign this user can belong to.

The User Actor has three jobs:

Determine which campaigns a specific app user can be a possible subscriber;

Serialize all of the data for this user into a linear sequence, based on when the message arrived, and hand this data over to the Campaign State Actors for filtering; and

Automatically shut down the User Actor if the user stops being active.

Items #1 and #2 are pretty generic, but item #3 is more interesting – how do we determine that an app user is no longer using their application?

We do this by setting a “Receive Time” that marks the UTC time a user last received a message from our API:

SetLastReceive();
SendToFilter(m);
nextState = Stay();

The SetLastReceive function sets this time value, and then we have a timer using Akka.NET’s FSM’s built-in scheduler that checks on whether on not this user is still active once every 60 seconds:

Then the User Actor stops itself and all of the CampaignState actors beneath it. This is how we free up memory and resources for future actors.

The Campaign State actor itself is another FSM and it communicates with a group of dedicated “Filter Actors” who process the campaign’s rules via a domain-specific language we invented for filtering. All the Campaign State actor does it process the results from the Filter Actors and save its state to Cassandra or send messages to the user if the user’s event stream satisfies all of the requirements for a campaign.

Communication between Remote Actor Systems with Akka.Remote

The MarkedUp API and the Targeting System communicate with each other via Akka’s Remoting features using a TCP socket and Google’s protocol buffers, and the MarkedUp API uses the ActorUri and ActorPath convention I showed you earlier to ensure that these messages are routed directly to the API Router Actor on the Targeting System.

The MessagePublishingActor lives inside the MarkedUp API and uses a RoundRobinGroup router to communicate with specific, named Actors on a remote system.

In production we can have several Targeting System’s serving as routees and we use a ConsistentHash router to make sure that all messages for the same user always arrive at the same server, but for the sake of brevity I rewrote this use a single server and a RoundRobinGroup router.

A RoundRobinGroup is different from a RoundRobinPool in that the RoundRobinGroup doesn’t directly supervise or manage it routees – it forwards messages to actors that are pre-created, whereas the RoundRobinPool creates and manages the worker actors themselves.

The important part, however, is the addressing – using the /user/api convention, which is the valid ActorPath for the API Router Actor on the Targeting System, Akka will automatically route my messages from the API server to the Targeting System via TCP, and then Akka’s remoting internals will ensure that these messages are correctly routed to this actor.

As for the messages themselves, and this is important – both the MarkedUp API and the Targeting System share a common assembly that defines all of the message types that can be exchange over the network. Otherwise we couldn’t deserialize any of those messages at the other end of the network connection.

Wrapping Up

Akka.NET has been a boon to our productivity, because of how simple its programming model is – instead of writing a piece of code that tries to determine campaign eligibility for 10,000 users in parallel, we can write a piece of code that makes that determination for a single user and run 10,000 instances of it with minimal overhead.

The actor model does an excellent job of atomizing code into very small parts, particularly because actors can only process one message in their inbox at a time (except for router actors.) The serial nature of message processing inherently makes everything inside an actor thread-safe, so you can store local state inside each actor instead of having to rely on a big synchronized cache or polling a distributed cache in Redis / Memcached.

We’ll have some more posts in the future about some of the other cool stuff we’re using Actors for and some of the integrations we’ve set up, such as our live debugger using SignalR and Akka.NET’s logging capabilities.

]]>http://blog.markedup.com/2014/07/real-time-marketing-automation-with-distributed-actor-systems-and-akka-net/feed/3MarkedUp 1.3.5: Now with .NET 3.5 and .NET 4.0 Client Profile Supporthttp://blog.markedup.com/2014/07/markedup-1-3-5now-with-net-3-5-and-net-4-0-client-profile-support/
http://blog.markedup.com/2014/07/markedup-1-3-5now-with-net-3-5-and-net-4-0-client-profile-support/#commentsWed, 02 Jul 2014 04:54:22 +0000https://blog.markedup.com/?p=6051Continued]]>Earlier this evening the MarkedUp team pushed MarkedUp v1.3.5 to NuGet – the changes include some relatively minor bug fixes, but the major new change is the addition of both .NET 3.5 and .NET 4.0 client profile support for Windows Desktop applications.

NuGet will automatically install the appropriate version of MarkedUp into your application, depending on your Visual Studio project settings.

Our documentation has already been updated to include the SDK reference and integration requirements for all three of these platforms, so you can find all of the good technical stuff there. We support everything that the WinRT and Windows Phone SDKs do.

Some statistics:

We’ve successfully integrated MarkedUp Analytics for Native C/C++ into popular, well-known applications whose codebases are 22 years old (originally written for Windows 3.1) without any issues. If MarkedUp can run there, it can run anywhere.

MarkedUp has been successfully deployed on over 250,000 Windows XP, Vista, Windows 7, and Windows 8 system without any problems. If MarkedUp gets deployed onto a system that’s missing one of our system requirements, MarkedUp is smart enough to simply no-op all of its calls and fail gracefully for those users.

The entire MarkedUp SDK for Native C/C++, including the tray client for In-app marketing, adds just 500k to the size of an install package when compressed, and has had no measurable impact on download completion rates or install rates for any of our beta customers (a good thing.)

Now, here’s the exciting part…

Introducing MarkedUp In-app Marketing Automation for Windows Desktop

MarkedUp In-app Marketing has been our secret skunkworks project for quite some time now, and we’ve made it available first for Windows Desktop applications.

MarkedUp In-app Marketing allows app developers to improve user retention, time spent in app, conversion, and revenue through targeted campaigns of push notifications that are delivered instantly to end-users based on their behavior inside the app.

Once you’ve installed MarkedUp into your app, you never need to update your application again in order to create new campaigns, new messages, or target new groups of users – you can do all of this on-the-fly from your MarkedUp dashboard.

We’ve done what MixPanel, Urban Airship, and a boatload of other well-funded companies should have figured out a long time ago: horizontal integration between event analytics and marketing automation makes things really simple for everybody.

Add Your First Windows Desktop App to MarkedUp

Want to try all of this good stuff out? Good – it’s still just as easy as before.

Create a new app and select any of the following from the “primary platform” list:

And that’s it – you’re off to the races.

]]>http://blog.markedup.com/2014/06/full-support-for-windows-desktop-applications-native-c-c-wpf-and-windows-forms/feed/0And Now for Something Totally Different… Real-time, In-app Marketing Automation Powered by MarkedUp Analyticshttp://blog.markedup.com/2014/06/and-now-for-something-totally-different-real-time-in-app-marketing-automation-powered-by-markedup-analytics/
http://blog.markedup.com/2014/06/and-now-for-something-totally-different-real-time-in-app-marketing-automation-powered-by-markedup-analytics/#commentsWed, 11 Jun 2014 21:32:41 +0000https://blog.markedup.com/?p=5991Continued]]>When we first started MarkedUp, we did it with the goal of making it easier for software publishers to focus on making great products, rather than worrying about how to market and sell their wares.

MarkedUp In-app Marketing allows app developers to improve user retention, time spent in app, conversion, and revenue through targeted campaigns of push notifications that are delivered instantly to end-users based on their behavior inside the app.

Once you’ve installed MarkedUp into your app, you never need to update your application again in order to create new campaigns, new messages, or target new groups of users – you can do all of this on-the-fly from your MarkedUp dashboard.

In-app Marketing?

Even if you’ve never heard the term before, in-app marketing becomes part of your life the moment you release a piece of software to the public, whether it’s in the form of trying to get people to pay for a licensed version, write a review in the app store, invite their friends to your service, and so forth.

In-app marketing is how you use the features and design of your software itself to achieve these business outcomes, and with MarkedUp In-app Marketing we’ve just given you a powerful new suite of tools that make it really easy to test, improve, and create new in-app marketing tactics specific to your application on the fly.

Here’s how MarkedUp In-app Marketing works in relation to our other services and your app:

You deploy the MarkedUp SDK along with your app, start sending session events, and then create campaigns which are delivered directly to end-users via push notification.

What’s revolutionary about this idea is the integration between MarkedUp Analytics and In-app Marketing. The same session events, navigation events, and demographic data that MarkedUp Analytics collects is what you use to target your campaigns to specific groups of users.

Real World Use Cases

Here are some ideal use case where MarkedUp In-app Marketing can help app developers of any shape or size:

Re-engage users who’ve stopped using your application;

Help new users get more familiar with your application so they become lifelong users;

Drive app store ratings, reviews, and social recommendations;

Promote other titles, updates, or new features;

And drive sales or upgrades with targeted offers.

All of these use-cases revolve around the idea of targeting users based on their actual behavior inside your app, which is obnoxiously difficult to do even with platforms like MixPanel and Urban Airship.

MarkedUp In-app Marketing is the first service that makes this type of targeting mind-numbingly easy, using our session events API and other data we already collect for each user.

Demo

Want to see what MarkedUp In-app Marketing looks like, end-to-end with a live desktop application? You’ve got it. Check out the video below – it’ll take less than five minutes.

MarkedUp In-app Marketing is currently only available for Windows Desktop applications. If you’re interested trying In-app Marketing for your Windows Store or Windows Phone application, sign up here.

]]>http://blog.markedup.com/2014/06/and-now-for-something-totally-different-real-time-in-app-marketing-automation-powered-by-markedup-analytics/feed/0MarkedUp Analytics is now Available for Universal Apps and Windows Phone 8.1http://blog.markedup.com/2014/05/markedup-analytics-is-now-available-for-universal-apps-and-windows-phone-8-1/
http://blog.markedup.com/2014/05/markedup-analytics-is-now-available-for-universal-apps-and-windows-phone-8-1/#commentsThu, 01 May 2014 17:45:24 +0000https://blog.markedup.com/?p=5981Continued]]>It’s that time of year again, when //BUILD comes, goes, and invents a totally new way of writing native apps for the Windows Store yet again.

The biggest difference between these platforms isn’t the code used to write the applications (although that’s different too,) it’s the that the Windows Phone 8.1 (Windows Store) gives you the ability to sell your app in any marketplace where WinRT is supported – which are the Windows Phone and Windows Store marketplaces today, and includes the Xbox and other platforms tomorrow.

The Windows Phone 8.1 (Silverlight) platform is just an upgrade for existing Windows Phone-only applications, and doesn’t do much beyond give you access to the new APIs introduced in Windows Phone 8.1. We wouldn’t be surprised if Microsoft deprecated Silverlight-based applications in their entirety within the next couple of releases.

Here’s a comparison chart that we put together which makes it easy to figure out which project type (Silverlight or Windows Store) you need for your specific use case:

MarkedUp Analytics has 100% feature parity on both platforms as of this release, so no matter which flavor of Windows Phone application you pick, you can enjoy full support from MarkedUp Analytics.

Universal Apps

Universal Apps are a new addition to the Windows Store family, although the concept itself is not new – iOS and Android have both had support for universal phone/tablet applications for some time.

You can create universal applications in any of the supported WinRT languages: C#, JavaScript, and C++.

Installing MarkedUp into a Universal App is identical to installing it into a stand-alone WinRT or Windows Phone application – the only difference is that you have to install MarkedUp into both the Windows 8.1 and the Windows Phone 8.1 project.

Once that’s done, you can call MarkedUp inside the Shared/App.xaml.cs file.

Then we initialize the SDK using an API key – this will use the same API key across both Windows Phone and Windows Store versions of your app.

If you want to be able to track the installs and downloads of your Windows Phone and Windows versions of the same app separately, you can accomplish this easily using the WINDOWS_APP and WINDOWS_PHONE_APP built-in pre-compilation directives that Universal Apps make available to you:

All of the MarkedUp APIs are identical to what’s in our SDK reference for Windows Store applications – we’ve updated some of the code under the hood to reflect some of the changes introduced in Windows 8.1, but these are all invisible to developers like you.

]]>http://blog.markedup.com/2014/05/markedup-analytics-is-now-available-for-universal-apps-and-windows-phone-8-1/feed/0Announcing Pricing for MarkedUp Analyticshttp://blog.markedup.com/2014/02/announcing-pricing-for-markedup-analytics/
http://blog.markedup.com/2014/02/announcing-pricing-for-markedup-analytics/#commentsTue, 18 Feb 2014 19:12:10 +0000https://blog.markedup.com/?p=5801Continued]]>Today we’re announcing pricing for MarkedUp. One of the biggest concerns we’ve heard from customers over the past year and a half is that they haven’t been able to pay us for our service. We know that you want us to be around for years to come so you can use our services in all of your applications.

MarkedUp Analytics has been available in public beta since October 2012, and I wanted to share some data about our progress.

Since 2012 we’ve had more than 40 million devices run over 1000 apps over 180 million times! We’ve observed more than 10 million crashes and 80 million exceptions JavaScript and C#. And most impressively, we’ve observed over a 1 billion session events.

And we could not have done any of this without developers like you using our service. Thank you!

We care deeply about our community, which is why we’ve responded to over 300 support tickets from our users within a business day – most of them within the hour! We’ve enjoyed building a community on our twitter account and facebook page and we’ve spoken with many of our users over Skype, email, and in-person at conferences like //BUILD and the Cassandra Summit.

When I founded MarkedUp, I wanted to make it easy for app developers to see how their end-users actually use their apps. I wanted to make you excited when you saw users around the world install your brand new app in real-time, make you aware when your app is crashing and having trouble, and help you discover who your paying customers are.

We’re fully committed to always having a free tier. It’s central to our values as software developers ourselves. We want to make sure that developers can test and deploy new applications on our platform at no cost.

Pricing Plans for Apps

Maximum Users

Monthly Cost

Free

10,000

-

50K Users

50,000

$49

100K Users

100,000

$99

300K Users

300,000

$150

1M Users

1,000,000

$450

Unlimited

Unlimited

$1,000

MarkedUp’s perpetual free tier covers all apps with fewer than 10,000 distinct monthly users – beyond that paid plans begin at $49 a month and will have access to some yet-to-be-announced new features and services that will be coming soon.

We chose to charge based off of the number of users because sticking with our original pricing plan, charging per the volume of data collected, would have been… kind of insane.

Accruing a million data points in a month is astonishingly easy. And while we do need to be able to build a sustainable revenue stream in order to ensure that MarkedUp is around for years to come, nickel-and-diming our users who every log message and session event they collect is not the way to do it.

How to Upgrade Your App to a Premium Plan

You can upgrade to your app by going to the new “Plans” tab on your dashboard.

And select the most appropriate plan from the list:

And then follow the steps in the checkout wizard to complete your upgrade.

I will be reaching out to all customers who will be impacted by these pricing changes. Your service will not be interrupted – we will always collect data on your behalf even if you have an outstanding bill.

It’s important to note that after you select your plan you will not be charged until March 1st, when this pricing goes into effect. MarkedUp will charge you at the beginning of each month going forward, based on your previous month’s usage.

A Special Gift for MarkedUp Beta Users

I’ve communicated with many of you individually about our pricing already, long before this announcement. I’m amazed by our community – we have intelligent customers who build exceptional apps and whose feedback we’ve directly incorporated into MarkedUp’s features and product roadmap.

So as a way of saying thank you to all of you, we’re offering a 50% discount on all premium plans for 12 months to everyone who upgrades to a paid plan before March 1st.

Go to your plans page for all apps you want to upgrade and use the coupon code BETACUSTOMER to activate your discount.

And once you’ve hit the “Apply” button on the plans page, you’ll see the pricing drop immediately for all plans.

And there you have it. This coupon is only good if you use it before March 1st, so activate it soon!

If you have any questions about our pricing our billing practices, please contact me and the rest of the MarkedUp team at support@markedup.com – we’ll provide you with a speedy reply to any of your questions!

]]>http://blog.markedup.com/2014/02/announcing-pricing-for-markedup-analytics/feed/0It’s All About Price: Microsoft’s Surface RT $150 Price Drop Tripled Monthly Sales Volume Throughout 2013http://blog.markedup.com/2014/02/microsofts-surface-rt-150-price-drop-tripled-monthly-sales-volume-2013/
http://blog.markedup.com/2014/02/microsofts-surface-rt-150-price-drop-tripled-monthly-sales-volume-2013/#commentsThu, 06 Feb 2014 15:29:10 +0000https://blog.markedup.com/?p=5651Continued]]>A lot has happened since we released our last report on the traction of Microsoft’s Surface RT and Surface Pro Tablets in the marketplace!

The chart above plots the total number of known Surface RT 1 units that connected to MarkedUp’s services over the course of the past year.

As you can see, the Surface RT 1 had sluggish adoption in early 2013 but rapidly accelerated beginning in March / April – the likely cause of that growth is due to Microsoft’s introduction of the Surface RT tablet into new markets and additional promotions /exposure described earlier.

However, the Surface RT’s growth really exploded around the June / July 2013 timeframe – right when the Surface’s prices slashed. Bear in mind that late Summer and Winter are Microsoft’s two strongest sales quarters for consumer products – “Back to School” and “Holiday” sales respectively.

Average number of monthly Surface RT 1 units sold prior to price drop

105,452 monthly units

Average number of monthly Surface RT 1 units sold after to price drop

358,044 monthly units

As you can see from the data table above, the monthly sales volume of Microsoft’s Surface RT 1 units tripled following the price cut – moving from roughly 100,000 units per month to 350,000 per month.

We plotted the net number of new devices per month to help confirm this:

You can see a big ramp up of sales in July and August, followed by a drop in September. That’s natural – back to school sales typically end by Labor Day in early September, so there’s going to be a big drop following August.

But what’s really telling about this graph is that the number of units sold in September is still greater than what was sold in July (another strong B2S sales month), which is unusual. Here’s the raw data table to supplement the chart.

Surface RT 1 Worldwide Adoption January 2013-2014

Month

New Devices

Total Devices

2013-01

75,535

75,535

2013-02

72,701

148,236

2013-03

83,678

231,914

2013-04

96,134

328,048

2013-05

120,522

448,570

2013-06

184,140

632,710

2013-07

246,299

879,009

2013-08

339,794

1,218,803

2013-09

249,798

1,468,601

2013-10

318,291

1,786,892

2013-11

321,131

2,108,023

2013-12

556,965

2,664,988

2014-01

474,030

3,139,018

It was generally believed that issues with the Windows 8 and Surface RT user experience were the tablet’s primary barriers to adoption. It is our conclusion that the real issues might have been awareness and price sensitivity.

So why is the Surface product line starting to look healthier for Microsoft now? Is the Surface 2 or Surface Pro such a drastic improvement over the Surface RT tablets that it’s been able to single-handedly double Microsoft’s Surface revenue? Not exactly.

By the end of December 2013, we started seeing roughly 60,000 new Surface RT 2 devices activated per month – a pretty good start for a new device that’s still trying to build up brand recognition with consumers.

However, its older cousin, the Surface RT 1, sold well over 500,000 copies in December.

Surface RT 1 vs. Surface RT 2 Devices Activated per Month

Month

Surface RT 1

Surface RT 2

2013-01

75,535

0

2013-02

72,701

0

2013-03

83,678

0

2013-04

96,134

0

2013-05

120,522

0

2013-06

184,140

0

2013-07

246,299

0

2013-08

339,794

131

2013-09

249,798

130

2013-10

318,291

10,315

2013-11

321,131

34,476

2013-12

556,965

62,905

2014-01

474,030

61,340

Total

3,139,018

169,299

Conclusion

It’s difficult to reconcile this data with the theory that the Surface RT 1’s inability to meet Microsoft’s original sales estimate was due to the product design itself, if you assume that the Surface RT 2 is an improved product (which it is.)

Aside from the innate improvements made to the Surface 2 and its novelty, the only other major difference between the two generations of Surface is price. Microsoft moves many times more tablets when the starting price point is at $349 versus $499.

In a subsequent update, we will perform a similar analysis for the higher-end Surface Pro and Surface Pro 2 tablets.

MarkedUp’s Collection Methods

Our data is collected from apps that are installed directly onto end-user machines, so our data set is limited to “devices that have installed an app that uses MarkedUp.”

That being said, this data set is covers roughly 10% of all Windows 8 machines ever sold. Our numbers for Windows Phone are similarly impressive, but excluded from this data-set (naturally.)

There is some latency between when a device is sold to an end-user and when we “discover” it by way of an app installation; however, having been in market since before Windows 8 was launched, our data set has historically mirrored the market as it moves in real-time. We see giant surges on Christmas morning, after Black Friday, and so forth.

Devices can be counted multiple times, depending on the number of installed apps from distinct MarkedUp-enabled publishers and the version of our SDK that was used. Our facts and figures accurately reflect trends and changes in direction in the market, but not precise figures.

These reports are anonymized aggregations of our entire data-set.

The data in this report tracks the number of net new devices activated on our platform per month, starting from January 2013 to January 2014.

]]>http://blog.markedup.com/2014/02/microsofts-surface-rt-150-price-drop-tripled-monthly-sales-volume-2013/feed/0The Future of MarkedUp: Support for all Major Native App Platformshttp://blog.markedup.com/2014/02/future-markedup-support-major-native-app-platforms/
http://blog.markedup.com/2014/02/future-markedup-support-major-native-app-platforms/#commentsTue, 04 Feb 2014 15:30:20 +0000https://blog.markedup.com/?p=5511Continued]]>MarkedUp Users and Customers,

If you’ve logged into your MarkedUp Analytics dashboards in the past day or so, you might have been surprised by the new look and feel of our site. We hope you enjoy it!

Coming Soon: MarkedUp Analytics for Windows Desktop Applications

The first new platform that MarkedUp will fully support is Win32 – the platform used for building traditional Windows desktop applications.

We may have mobile and touch platforms like iOS and Android to thank for the resurgence of native application development over the past five years, but the Windows Desktop is the original developer platform.

The Windows Desktop economy is strong and growing, doing over $100b+ a year in license + services sales directly to end-users annually.

However, it’s a market that largely predates the Internet – and thus it’s had trouble adopting all of the software sales + marketing + product best practices that are commonly used throughout modern software development shops, largely due to lack of third party services and tools.

Modern software development practices depend on connected services like analytics and marketing automation to in order to make data-driven decisions, and it’s MarkedUp Analytics’ intention to finally make some of these services available to Windows Desktop developers.

The details

MarkedUp Analytics will support the following flavors of Win32 development:

Windows Forms: .NET 3.5 and later

Windows Presentation Foundation: .NET 3.5 and later

Native C/C++: Windows XP and later

Holy crap, you’re supporting C/C++ applications for Windows?!?!?!

Yes! Our native C/C++ components will support the all of the same APIs that are available in the .NET flavors of our Win32 SDK.

Worth noting: our C/C++ SDKs will depend on .NET.

How will your WPF / WinForms support compare to your WinRT and Windows Phone APIs?

They’re virtually identical. The only major difference is that our .NET 3.5 / .NET 4.0 / .NET 4.5 SDKs for WPF and WinForms development will expose more methods for manually handling events such as app start / termination.

Win32, by its very nature, is a much more open platform than WinRT / Windows Phone and thus the developers have a lot more options when it comes to how they manage the lifecycle of their applications.

Thus, we decided it would be inappropriate for MarkedUp to try to automate some of the things we do on WinRT and Windows Phone.

iOS and Android

There are a ton of choices for iOS and Android when it comes to app analytics and reporting – when we were developing apps ourselves, we frankly felt that many of these services were difficult to use, had sub-standard reporting, and non-existent service.

We still feel that way.

Thus, we are making it a goal of our to provide support for iOS and Android in the near future! They’re further out than Win32 support, but we’ll keep you updated on the latest.