diff --git a/app/assets/javascripts/discourse/controllers/user_invited_controller.js b/app/assets/javascripts/discourse/controllers/user_invited_controller.js
index 4548bdb56..877871bfb 100644
--- a/app/assets/javascripts/discourse/controllers/user_invited_controller.js
+++ b/app/assets/javascripts/discourse/controllers/user_invited_controller.js
@@ -2,11 +2,31 @@
   This controller handles actions related to a user's invitations
 
   @class UserInvitedController
-  @extends Discourse.ObjectController
+  @extends Ember.ArrayController
   @namespace Discourse
   @module Discourse
 **/
-Discourse.UserInvitedController = Discourse.ObjectController.extend({
+Discourse.UserInvitedController = Ember.ArrayController.extend({
+
+  _searchTermChanged: Discourse.debounce(function() {
+    var self = this;
+    Discourse.Invite.findInvitedBy(self.get('user'), this.get('searchTerm')).then(function (invites) {
+      self.set('model', invites);
+    });
+  }, 250).observes('searchTerm'),
+
+  maxInvites: function() {
+    return Discourse.SiteSettings.invites_shown;
+  }.property(),
+
+  showSearch: function() {
+    if (Em.isNone(this.get('searchTerm')) && this.get('model.length') === 0) { return false; }
+    return true;
+  }.property('searchTerm', 'model.length'),
+
+  truncated: function() {
+    return this.get('model.length') === Discourse.SiteSettings.invites_shown;
+  }.property('model.length'),
 
   actions: {
     rescind: function(invite) {
diff --git a/app/assets/javascripts/discourse/models/invite.js b/app/assets/javascripts/discourse/models/invite.js
index 503fc58df..00b5a35b6 100644
--- a/app/assets/javascripts/discourse/models/invite.js
+++ b/app/assets/javascripts/discourse/models/invite.js
@@ -27,6 +27,19 @@ Discourse.Invite.reopenClass({
       result.user = Discourse.User.create(result.user);
     }
     return result;
+  },
+
+  findInvitedBy: function(user, filter) {
+    if (!user) { return Ember.RSVP.resolve(); }
+
+    var data = {};
+    if (!Em.isNone(filter)) { data.filter = filter; }
+
+    return Discourse.ajax("/users/" + user.get('username_lower') + "/invited.json", {data: data}).then(function (result) {
+      return result.map(function (i) {
+        return Discourse.Invite.create(i);
+      });
+    });
   }
 
 });
diff --git a/app/assets/javascripts/discourse/models/invite_list.js b/app/assets/javascripts/discourse/models/invite_list.js
deleted file mode 100644
index 43376f998..000000000
--- a/app/assets/javascripts/discourse/models/invite_list.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
-  A data model representing a list of Invites
-
-  @class InviteList
-  @extends Discourse.Model
-  @namespace Discourse
-  @module Discourse
-**/
-Discourse.InviteList = Discourse.Model.extend({
-  empty: (function() {
-    return this.blank('pending') && this.blank('redeemed');
-  }).property('pending.@each', 'redeemed.@each')
-});
-
-Discourse.InviteList.reopenClass({
-
-  findInvitedBy: function(user) {
-    return Discourse.ajax("/users/" + (user.get('username_lower')) + "/invited.json").then(function (result) {
-      var invitedList = result.invited_list;
-      if (invitedList.pending) {
-        invitedList.pending = invitedList.pending.map(function(i) {
-          return Discourse.Invite.create(i);
-        });
-      }
-      if (invitedList.redeemed) {
-        invitedList.redeemed = invitedList.redeemed.map(function(i) {
-          return Discourse.Invite.create(i);
-        });
-      }
-      invitedList.user = user;
-      return Discourse.InviteList.create(invitedList);
-    });
-  }
-
-});
-
-
diff --git a/app/assets/javascripts/discourse/models/nav_item.js b/app/assets/javascripts/discourse/models/nav_item.js
index fcba5f39a..2c947886d 100644
--- a/app/assets/javascripts/discourse/models/nav_item.js
+++ b/app/assets/javascripts/discourse/models/nav_item.js
@@ -1,7 +1,7 @@
 /**
   A data model representing a navigation item on the list views
 
-  @class InviteList
+  @class NavItem
   @extends Discourse.Model
   @namespace Discourse
   @module Discourse
diff --git a/app/assets/javascripts/discourse/routes/user_invited_route.js b/app/assets/javascripts/discourse/routes/user_invited_route.js
index 420b730ed..2c72df220 100644
--- a/app/assets/javascripts/discourse/routes/user_invited_route.js
+++ b/app/assets/javascripts/discourse/routes/user_invited_route.js
@@ -12,11 +12,15 @@ Discourse.UserInvitedRoute = Discourse.Route.extend({
   },
 
   model: function() {
-    return Discourse.InviteList.findInvitedBy(this.modelFor('user'));
+    return Discourse.Invite.findInvitedBy(this.modelFor('user'));
   },
 
   setupController: function(controller, model) {
-    controller.set('model', model);
+    controller.setProperties({
+      model: model,
+      user: this.controllerFor('user').get('model'),
+      searchTerm: ''
+    });
     this.controllerFor('user').set('indexStream', false);
   }
 
diff --git a/app/assets/javascripts/discourse/templates/user/email.js.handlebars b/app/assets/javascripts/discourse/templates/user/email.js.handlebars
index 978e42a8f..bb3e812d7 100644
--- a/app/assets/javascripts/discourse/templates/user/email.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/user/email.js.handlebars
@@ -1,46 +1,48 @@
-<form class="form-horizontal">
+<section class='user-content'>
+  <form class="form-horizontal">
 
-  <div class="control-group">
-    <div class="controls">
-      <h3>{{i18n user.change_email.title}}</h3>
+    <div class="control-group">
+      <div class="controls">
+        <h3>{{i18n user.change_email.title}}</h3>
+      </div>
     </div>
-  </div>
 
-  {{#if success}}
+    {{#if success}}
+        <div class="control-group">
+          <div class="instructions">
+            <p>{{i18n user.change_email.success}}</p>
+          </div>
+        </div>
+    {{else}}
+      {{#if error}}
+        <div class="control-group">
+          <div class="instructions">
+            <div class='alert error'>{{i18n user.change_email.error}}</div>
+          </div>
+        </div>
+      {{/if}}
+
       <div class="control-group">
-        <div class="instructions">
-          <p>{{i18n user.change_email.success}}</p>
+        <label class="control-label">{{i18n user.email.title}}</label>
+        <div class="controls">
+          {{textField value=newEmail id="change_email" classNames="input-xxlarge"}}
+        </div>
+        <div class='instructions'>
+          {{#if taken}}
+            {{i18n user.change_email.taken}}
+          {{else}}
+            {{i18n user.email.instructions}}
+          {{/if}}
+
         </div>
       </div>
-  {{else}}
-    {{#if error}}
+
       <div class="control-group">
-        <div class="instructions">
-          <div class='alert error'>{{i18n user.change_email.error}}</div>
+        <div class="controls">
+            <button {{action changeEmail}} {{bindAttr disabled="saveDisabled"}} class="btn btn-primary">{{saveButtonText}}</button>
         </div>
       </div>
     {{/if}}
 
-    <div class="control-group">
-      <label class="control-label">{{i18n user.email.title}}</label>
-      <div class="controls">
-        {{textField value=newEmail id="change_email" classNames="input-xxlarge"}}
-      </div>
-      <div class='instructions'>
-        {{#if taken}}
-          {{i18n user.change_email.taken}}
-        {{else}}
-          {{i18n user.email.instructions}}
-        {{/if}}
-
-      </div>
-    </div>
-
-    <div class="control-group">
-      <div class="controls">
-          <button {{action changeEmail}} {{bindAttr disabled="saveDisabled"}} class="btn btn-primary">{{saveButtonText}}</button>
-      </div>
-    </div>
-  {{/if}}
-
-</form>
+  </form>
+</section>
\ No newline at end of file
diff --git a/app/assets/javascripts/discourse/templates/user/invited.js.handlebars b/app/assets/javascripts/discourse/templates/user/invited.js.handlebars
index 9488a2d7d..af8965883 100644
--- a/app/assets/javascripts/discourse/templates/user/invited.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/user/invited.js.handlebars
@@ -1,70 +1,59 @@
-<div id='invited-users'>
-  {{#if empty}}
-    <div id='no-invites' class='boxed white'>
-      {{i18n user.invited.none username="user.username"}}
-    </div>
-  {{else}}
-    {{#if redeemed}}
-      <div class='invites'>
-        <h2>{{i18n user.invited.redeemed}}</h2>
-        <div class='boxed white'>
-          <table class='table'>
-            <tr>
-              <th>{{i18n user.invited.user}}</th>
-              <th>{{i18n user.invited.redeemed_at}}</th>
-              <th>{{i18n user.last_seen}}</th>
-              <th>{{i18n user.invited.topics_entered}}</th>
-              <th>{{i18n user.invited.posts_read_count}}</th>
-              <th>{{i18n user.invited.time_read}}</th>
-              <th>{{i18n user.invited.days_visited}}</th>
-            </tr>
-            {{#each redeemed}}
-              <tr>
-                <td>
-                  <a href="{{unbound user.path}}">{{avatar user imageSize="tiny"}}</a>
-                  <a href="{{unbound user.path}}">{{user.username}}</a>
-                </td>
-                <td>{{date redeemed_at}}</td>
-                <td>{{date user.last_seen_at}}</td>
-                <td>{{number user.topics_entered}}</td>
-                <td>{{number user.posts_read_count}}</td>
-                <td>{{{unbound user.time_read}}}</td>
-                <td><span title="{{i18n user.invited.days_visited}}">{{{unbound user.days_visited}}}</span>
-                    /
-                    <span title="{{i18n user.invited.account_age_days}}">{{{unbound user.days_since_created}}}</span></td>
-              </tr>
-            {{/each}}
-          </table>
-        </div>
-      </div>
+<section class='user-content'>
+
+  <h2>{{i18n user.invited.title}}</h2>
+
+  {{#if showSearch}}
+  <form>
+    {{textField value=searchTerm placeholderKey="user.invited.search"}}
+  </form>
+  {{/if}}
+
+  {{#if model}}
+    <table class='table'>
+      <tr>
+        <th>{{i18n user.invited.user}}</th>
+        <th>{{i18n user.invited.redeemed_at}}</th>
+        <th>{{i18n user.last_seen}}</th>
+        <th>{{i18n user.invited.topics_entered}}</th>
+        <th>{{i18n user.invited.posts_read_count}}</th>
+        <th>{{i18n user.invited.time_read}}</th>
+        <th>{{i18n user.invited.days_visited}}</th>
+      </tr>
+      {{#each model}}
+        <tr>
+          {{#if user}}
+          <td>
+            {{#linkTo 'user' user}}{{avatar user imageSize="tiny"}}{{/linkTo}}
+            {{#linkTo 'user' user}}{{user.username}}{{/linkTo}}
+          </td>
+          <td>{{date redeemed_at}}</td>
+          <td>{{date user.last_seen_at}}</td>
+          <td>{{number user.topics_entered}}</td>
+          <td>{{number user.posts_read_count}}</td>
+          <td>{{{unbound user.time_read}}}</td>
+          <td><span title="{{i18n user.invited.days_visited}}">{{{unbound user.days_visited}}}</span>
+              /
+              <span title="{{i18n user.invited.account_age_days}}">{{{unbound user.days_since_created}}}</span></td>
+          {{else}}
+            <td>{{unbound email}}</td>
+            <td colspan='6'>
+              {{#if rescinded}}
+                {{i18n user.invited.rescinded}}
+              {{else}}
+                <button class='btn' {{action rescind this}}>{{i18n user.invited.rescind}}</button>
+              {{/if}}
+            </td>
+          {{/if}}
+        </tr>
+      {{/each}}
+    </table>
+
+    {{#if truncated}}
+      <p>{{i18n user.invited.truncated count=maxInvites}}</p>
     {{/if}}
 
-    {{#if pending}}
-      <div class='invites'>
-        <h2>{{i18n user.invited.pending}}</h2>
-        <div class='boxed white'>
-          <table class='table'>
-            <tr>
-              <th style='width: 60%'>{{i18n user.email.title}}</th>
-              <th style='width: 20%'>{{i18n created}}</th>
-              <th>&nbsp;</th>
-            </tr>
-            {{#each pending}}
-              <tr>
-                <td>{{email}}</td>
-                <td>{{date created_at}}</td>
-                <td>
-                  {{#if rescinded}}
-                    {{i18n user.invited.rescinded}}
-                  {{else}}
-                    <button class='btn' {{action rescind this}}>{{i18n user.invited.rescind}}</button>
-                  {{/if}}
-                </td>
-              </tr>
-            {{/each}}
-          </table>
-        </div>
-      </div>
-    {{/if}}
+  {{else}}
+    {{i18n user.invited.none}}
   {{/if}}
-</div>
+
+</section>
\ No newline at end of file
diff --git a/app/assets/javascripts/discourse/templates/user/username.js.handlebars b/app/assets/javascripts/discourse/templates/user/username.js.handlebars
index ac1ec8a88..fd395fb6c 100644
--- a/app/assets/javascripts/discourse/templates/user/username.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/user/username.js.handlebars
@@ -1,37 +1,39 @@
-<form class="form-horizontal">
+<section class='user-content'>
+  <form class="form-horizontal">
 
-  <div class="control-group">
-    <div class="controls">
-      <h3>{{i18n user.change_username.title}}</h3>
-    </div>
-  </div>
-
-  {{#if error}}
     <div class="control-group">
-      <div class="instructions">
-        <div class='alert error'>{{i18n user.change_username.error}}</div>
+      <div class="controls">
+        <h3>{{i18n user.change_username.title}}</h3>
       </div>
     </div>
-  {{/if}}
 
-  <div class="control-group">
-    <label class="control-label">{{i18n user.username.title}}</label>
-    <div class="controls">
-      {{textField value=newUsername id="change_username" classNames="input-xxlarge" maxlength="15"}}
-    </div>
-    <div class='instructions'>
-      {{#if taken}}
-        {{i18n user.change_username.taken}}
-      {{/if}}
-      <span>{{ errorMessage }}</span>
-    </div>
-  </div>
+    {{#if error}}
+      <div class="control-group">
+        <div class="instructions">
+          <div class='alert error'>{{i18n user.change_username.error}}</div>
+        </div>
+      </div>
+    {{/if}}
 
-  <div class="control-group">
-    <div class="controls">
-        <button {{action changeUsername}} {{bindAttr disabled="saveDisabled"}} class="btn btn-primary">{{saveButtonText}}</button>
-        {{#if saved}}{{i18n saved}}{{/if}}
+    <div class="control-group">
+      <label class="control-label">{{i18n user.username.title}}</label>
+      <div class="controls">
+        {{textField value=newUsername id="change_username" classNames="input-xxlarge" maxlength="15"}}
+      </div>
+      <div class='instructions'>
+        {{#if taken}}
+          {{i18n user.change_username.taken}}
+        {{/if}}
+        <span>{{ errorMessage }}</span>
+      </div>
     </div>
-  </div>
 
-</form>
+    <div class="control-group">
+      <div class="controls">
+          <button {{action changeUsername}} {{bindAttr disabled="saveDisabled"}} class="btn btn-primary">{{saveButtonText}}</button>
+          {{#if saved}}{{i18n saved}}{{/if}}
+      </div>
+    </div>
+
+  </form>
+</section>
\ No newline at end of file
diff --git a/app/assets/stylesheets/desktop/user.scss b/app/assets/stylesheets/desktop/user.scss
index 6fb35437f..73cc0588a 100644
--- a/app/assets/stylesheets/desktop/user.scss
+++ b/app/assets/stylesheets/desktop/user.scss
@@ -89,23 +89,6 @@
   }
 }
 
-#no-invites {
-  padding: 10px;
-}
-
-#invited-users {
-  h2 {
-    color: $darkish_gray;
-    font-size: 20px;
-  }
-  .invites {
-    margin-bottom: 20px;
-    tr {
-      height: 45px;
-    }
-  }
-}
-
 .user-main {
   width: 850px;
   float: left;
@@ -124,6 +107,26 @@
     background-color: white;
     border: 1px solid #ddd;
     margin-bottom: 10px;
+
+    h2 {
+      margin-bottom: 10px;
+    }
+
+    table {
+      width: 100%;
+      margin-top: 10px;
+
+      th {
+        text-align: left;
+        border-bottom: 1px solid #aaa;
+        padding: 5px;
+      }
+
+      td {
+        padding: 5px;
+        border-bottom: 1px solid #ddd;
+      }
+    }
   }
 
   .about {
diff --git a/app/assets/stylesheets/mobile/user.scss b/app/assets/stylesheets/mobile/user.scss
index c0728bc03..3e36e04be 100644
--- a/app/assets/stylesheets/mobile/user.scss
+++ b/app/assets/stylesheets/mobile/user.scss
@@ -88,23 +88,6 @@
   }
 }
 
-#no-invites {
-  padding: 10px;
-}
-
-#invited-users {
-  h2 {
-    color: $darkish_gray;
-    font-size: 20px;
-  }
-  .invites {
-    margin-bottom: 20px;
-    tr {
-      height: 45px;
-    }
-  }
-}
-
 .user-main {
   clear: both;
   margin-bottom: 50px;
@@ -160,7 +143,7 @@
       margin-top: 0px;
       padding: 10px 10px 0 10px;
 
-      .btn { 
+      .btn {
         margin-bottom: 10px;
         float: none;
       }
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index b2a696a69..df19e15d1 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -85,8 +85,29 @@ class UsersController < ApplicationController
   end
 
   def invited
-    invited_list = InvitedList.new(fetch_user_from_params)
-    render_serialized(invited_list, InvitedListSerializer)
+    params.require(:username)
+    params.permit(:filter)
+
+    by_user = fetch_user_from_params
+
+    invited = Invite.where(invited_by_id: by_user.id)
+                    .includes(:user => :user_stat)
+                    .order('CASE WHEN invites.user_id IS NOT NULL THEN 0 ELSE 1 END',
+                           'user_stats.time_read DESC',
+                           'invites.redeemed_at DESC')
+                    .limit(SiteSetting.invites_shown)
+                    .references('user_stats')
+
+    unless guardian.can_see_pending_invites_from?(by_user)
+      invited = invited.where('invites.user_id IS NOT NULL')
+    end
+
+    if params[:filter].present?
+      invited = invited.where('(LOWER(invites.email) LIKE :filter) or (LOWER(users.username) LIKE :filter)', filter: "%#{params[:filter].downcase}%")
+                       .references(:users)
+    end
+
+    render_serialized(invited.to_a, InviteSerializer)
   end
 
   def is_local_username
diff --git a/app/models/invited_list.rb b/app/models/invited_list.rb
deleted file mode 100644
index 35e3a6bf9..000000000
--- a/app/models/invited_list.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# A nice object to help keep track of invited users
-class InvitedList
-
-  attr_accessor :pending
-  attr_accessor :redeemed
-  attr_accessor :by_user
-
-  def initialize(user)
-    @pending = []
-    @redeemed = []
-    @by_user = user
-
-    invited = Invite.where(invited_by_id: @by_user.id)
-                    .includes(:user => :user_stat)
-                    .order(:redeemed_at)
-    invited.each do |i|
-      if i.redeemed?
-        @redeemed << i
-      else
-        @pending << i unless i.expired?
-      end
-    end
-  end
-
-end
diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb
index 070b1115c..5921bb720 100644
--- a/app/models/site_setting.rb
+++ b/app/models/site_setting.rb
@@ -272,6 +272,7 @@ class SiteSetting < ActiveRecord::Base
 
   client_setting(:display_name_on_posts, false)
   client_setting(:enable_names, true)
+  client_setting(:invites_shown, 30)
 
   def self.call_discourse_hub?
     self.enforce_global_nicknames? && self.discourse_org_access_key.present?
diff --git a/app/serializers/invite_serializer.rb b/app/serializers/invite_serializer.rb
index 3b9c1a063..73989b96e 100644
--- a/app/serializers/invite_serializer.rb
+++ b/app/serializers/invite_serializer.rb
@@ -3,8 +3,6 @@ class InviteSerializer < ApplicationSerializer
   attributes :email, :created_at, :redeemed_at
   has_one :user, embed: :objects, serializer: InvitedUserSerializer
 
-
-
   def include_email?
     !object.redeemed?
   end
diff --git a/app/serializers/invited_list_serializer.rb b/app/serializers/invited_list_serializer.rb
deleted file mode 100644
index 58d9d1a8d..000000000
--- a/app/serializers/invited_list_serializer.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-class InvitedListSerializer < ApplicationSerializer
-
-  has_many :pending, serializer: InviteSerializer, embed: :objects
-  has_many :redeemed, serializer: InviteSerializer, embed: :objects
-
-
-  def include_pending?
-    scope.can_see_pending_invites_from?(object.by_user)
-  end
-end
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index cbbed3d2b..33a56aff7 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -324,9 +324,11 @@ en:
           other: "after {{count}} minutes"
 
       invited:
+        search: "type to search invites..."
         title: "Invites"
         user: "Invited User"
-        none: "{{username}} hasn't invited any users to the site."
+        none: "No invites were found."
+        truncated: "Showing the first {{count}} invites."
         redeemed: "Redeemed Invites"
         redeemed_at: "Redeemed At"
         pending: "Pending Invites"
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 626a1fc28..e8080081d 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -723,6 +723,7 @@ en:
 
     enable_names: "Allow users to show their full names"
     display_name_on_posts: "Also show a user's full name on their posts"
+    invites_shown: "Maximum invites shown on a user page"
 
   notification_types:
     mentioned: "%{display_username} mentioned you in %{link}"
diff --git a/spec/models/invite_spec.rb b/spec/models/invite_spec.rb
index 727914e28..8b84a8f4a 100644
--- a/spec/models/invite_spec.rb
+++ b/spec/models/invite_spec.rb
@@ -71,11 +71,6 @@ describe Invite do
           @invite.topics.should == [topic]
         end
 
-        it 'is pending in the invite list for the creator' do
-          InvitedList.new(inviter).pending.should == [@invite]
-        end
-
-
         context 'when added by another user' do
           let(:coding_horror) { Fabricate(:coding_horror) }
           let(:new_invite) { topic.invite_by_email(coding_horror, iceking) }
@@ -197,12 +192,6 @@ describe Invite do
         end
 
         it 'works correctly' do
-          # no longer in the pending list for that user
-          InvitedList.new(invite.invited_by).pending.should be_blank
-
-          # is redeeemed in the invite list for the creator
-          InvitedList.new(invite.invited_by).redeemed.should == [invite]
-
           # has set the user_id attribute
           invite.user.should == user